PInvokeStackImbalance был обнаружен из HDFDotNet 1.8.7

Я пытаюсь выполнить обновление до последних оболочек HDF5DotNet (1.8.7) и получаю следующие предупреждения (при работе в режиме DEBUG из VS2010):

Обнаружен PInvokeStackImbalance Сообщение: вызов функции PInvoke «HDF5DotNet! :: H5Fopen» привел к разбалансировке стека. Вероятно, это связано с тем, что подпись управляемого PInvoke не соответствует подписи неуправляемого целевого объекта. Убедитесь, что соглашение о вызовах и параметры подписи PInvoke соответствуют целевой неуправляемой подписи.

Я использую предварительно скомпилированные двоичные файлы (сборка HDF5DotNet для 32-разрядной версии .NET Framework 4.0), но получил тот же результат при компиляции из исходников.

Как ни странно, при выполнении моего приложения, которое вызывает оболочки HDF5DotNet в режиме, отличном от DEBUG, я не вижу проблем. Я заметил, что между 1.8.6 и 1.8.7 все соглашения о вызовах были переключены с Cdecl на StdCall. Может ли это быть причиной этого? Я видел другие форумы, в которых говорилось, что CallingConvention должен БЫТЬ Cdecl ...

Спасибо!


person Josh    schedule 26.05.2011    source источник


Ответы (1)


Да, вызов функции stdcall как cdecl или наоборот вызывает дисбаланс стека. Основное различие между этими соглашениями состоит в том, что с cdecl вызывающий отвечает за удаление аргументов из стека, а с stdcall отвечает вызываемый.

Думаю, в режиме выпуска у вас такая же ошибка. Но вы не получите сообщение об ошибке, потому что некоторые проверки во время выполнения отключены. Собственная программа выдает сбой в большинстве случаев, когда вы используете неправильное соглашение о вызовах, но похоже, что код взаимодействия .net имеет более надежную обработку стека, которая маскирует эту проблему.

person CodesInChaos    schedule 26.05.2011
comment
+1, это точно. MDA отключены в сборке выпуска или без подключенного отладчика. Предупреждение очень надежное и серьезная проблема. Это очень сложно, потому что может показаться, что он работает хорошо, пока вы не внесете в код, казалось бы, небольшие изменения и не вылетите из строя. Или, что еще хуже, он работает в отладочной сборке и не работает в выпуске. Изменение соглашения о вызовах действительно является классическим исправлением. - person Hans Passant; 27.05.2011