pinvokestackimbalance - как это исправить или отключить?

Я только что перешел на vs2010 с vs2008. Точно такое же решение, за исключением того, что теперь каждый отдельный вызов dll C ++ приводит к исключению pinvokestackimbalance.

Это исключение не срабатывает в 2008 году. У меня есть полный доступ к dll C ++ и к вызывающему приложению. Похоже, с pinvoke проблем не возникает, но эта проблема делает невозможной отладку других проблем; IDE постоянно останавливается, чтобы рассказать мне об этих вещах.

Например, вот подпись C #:

    [DllImport("ImageOperations.dll")]
    static extern void FasterFunction(
        [MarshalAs(UnmanagedType.LPArray)]ushort[] inImage, //IntPtr inImage, 
        [MarshalAs(UnmanagedType.LPArray)]byte[] outImage, //IntPtr outImage, 
        int inTotalSize, int inWindow, int inLevel);

Здесь ' Как это выглядит на стороне C ++:

#ifdef OPERATIONS_EXPORTS
#define OPERATIONS_API __declspec(dllexport)
#else
#define OPERATIONS_API __declspec(dllimport)
#endif
extern "C" {


OPERATIONS_API void __cdecl FasterFunction(unsigned short* inArray, 
                                       unsigned char* outRemappedImage,
                                       int inTotalSize, 
                                       int inWindow, int inLevel);

}

Что отличается между vs2010 и vs2008, что может вызвать появление этих исключений? Должен ли я добавлять другой набор параметров в директиву DllImport?

72
задан Ciro Santilli 新疆改造中心法轮功六四事件 21 August 2013 в 07:56
поделиться

1 ответ

Во-первых, поймите, что код неверен (и всегда был неверен). "pInvokeStackImbalance" - это не исключение как таковое, а управляемый помощник отладки. Он был выключен по умолчанию в VS2008, но многие люди не стали его включать, поэтому он включен по умолчанию в VS2010. MDA не работает в режиме выпуска, поэтому он не сработает, если вы собираете для выпуска.

В вашем случае соглашение о вызове неверно. DllImport по умолчанию использует CallingConvention.WinApi, что идентично CallingConvention.StdCall для кода x86 desktop. Должно быть CallingConvention.Cdecl.

Это можно сделать, отредактировав строку [DllImport("ImageOperations.dll")] следующим образом:

[DllImport("ImageOperations.dll", CallingConvention = CallingConvention.Cdecl)]

Для получения дополнительной информации смотрите эту ссылку MSDN

137
ответ дан 24 November 2019 в 12:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: