Если ваша экспортируемая функция объявлена с соглашением о вызовах __stdcall
в DLL, которая ее экспортирует, вам нужно импортировать ее в код C # с CallingConvention.StdCall
, а не Cdecl
.
Причиначто это несоответствие соглашения о вызовах выдает ошибку о "разбалансировке стека", потому что после вызова функции cdecl
вызывающий код должен корректировать регистр указателя стека после вызова функции, чтобы удалить параметры, переданные функции изстек.Однако, поскольку ваша функция на самом деле является функцией stdcall
, она сама выполняет это в используемой инструкции ret imm16
, поэтому ваш стек теряет память, когда вызывающий код тоже «очищает стек».
Следующийпроблема в том, что long
в C # и long
в MSVC имеют разные размеры, поэтому даже при соглашении о вызовах stdcall
вызываемая функция выдает количество байтов, соответствующее тому, что она считает правильным размером для списка параметров,но, поскольку long
в C # не совпадает с размером long
в MSVC, стек все еще не сбалансирован после инструкции ret imm16
в конце функции DLL.Тип C # int
соответствует long
, однако.