Я только что перешел на 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?
Во-первых, поймите, что код неверен (и всегда был неверен). "pInvokeStackImbalance" - это не исключение как таковое, а управляемый помощник отладки. Он был выключен по умолчанию в VS2008, но многие люди не стали его включать, поэтому он включен по умолчанию в VS2010. MDA не работает в режиме выпуска, поэтому он не сработает, если вы собираете для выпуска.
В вашем случае соглашение о вызове неверно. DllImport
по умолчанию использует CallingConvention.WinApi
, что идентично CallingConvention.StdCall
для кода x86 desktop. Должно быть CallingConvention.Cdecl
.
Это можно сделать, отредактировав строку [DllImport("ImageOperations.dll")]
следующим образом:
[DllImport("ImageOperations.dll", CallingConvention = CallingConvention.Cdecl)]
Для получения дополнительной информации смотрите эту ссылку MSDN