Подтвердить что ты не робот

Почему я получил "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-разрядной ОС.

4b9b3361

Ответ 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