Почему я получил "PInvokeStackImbalance был обнаружен" для этого простого примера?
Я создаю очень простой пример PInvoke:
extern "C" __declspec(dllexport) int Add(int a, int b)
{
return a + b;
}
[DllImport("CommonNativeLib.dll")]
extern public static int Add(int a, int b);
return NativeMethods.Add(a, b);
Но всякий раз, когда я вызываю вышеуказанный метод NativeMethods.Add
, я получаю следующий управляемый помощник по отладке:
обнаружен PInvokeStackImbalance Сообщение: вызов функции PInvoke "CommonManagedLib! CommonManagedLib.NativeMethods:: Add" не сбалансировал стек. Вероятно, это связано с тем, что управляемая подпись PInvoke не соответствует неуправляемой целевой сигнатуре. Убедитесь, что соглашение о вызове и параметры сигнатуры PInvoke соответствуют целевой неуправляемой сигнатуре.
Затем вызов завершается с ожидаемым значением возвращаемого значения, но появление сообщения MDA является раздражающим и тревожным - я пока не понимаю PInvoke, но из того, что я прочитал, я уверен, что моя подпись правильно - что я делаю неправильно?
Все это на 32-разрядной ОС.
Ответы
Ответ 1
Вместо этого вам нужно использовать
[DllImport("CommonNativeLib.dll", CallingConvention = CallingConvention.Cdecl)]
или
extern "C" __declspec(dllexport) int __stdcall Add(int a, int b) ...
поскольку обычные функции C работают иначе, чем функции Windows API; их "соглашения о вызовах" различны, что означает, что они проходят вокруг параметров. (Это было намечено на ошибку.)
Ответ 2
Положения дисбаланса стека либо являются сигнатурой, либо не соответствуют другим. Calling Convention по умолчанию вызывает соглашение stdcall. Когда ваше соглашение о вызове является stdcall вызываемым, очищает стек, если вы хотите, чтобы вызывающий абонент очищал соглашение о вызове cdecl для стека. вы можете найти более Здесь
Но если вы столкнулись из-за подписи, просто перейдите по ссылке выше
Решить проблемы дисбаланса стека на основе подписи с использованием расширения PInvoke