在c#中导入Visual c + + DLL时的非托管签名

时间:2017-03-23 09:51:59

标签: c# visual-c++ dllimport

我有一个用Visual C ++开发的DLL,我开始使用DllImport将它的功能导入到c#项目中。我已经实现了一些方法并且运行良好。

对于该特定方法,我收到以下错误:

Additional information: A call to PInvoke function 'SdkTest!SdkTest.Program::CLIENT_RealPlay' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

我试图实现的c ++方法有这个签名:

CLIENT_NET_API LLONG CALL_METHOD CLIENT_RealPlay(LLONG lLoginID, int nChannelID, HWND hWnd);

具有以下定义:

#define CLIENT_NET_API  __declspec(dllimport)
#define CALL_METHOD     __stdcall
#define LLONG   LONG

我的c#impelmentation如下:

[DllImport("dhnetsdk.dll")]
public static extern long CLIENT_RealPlay(long lLoginID, int nChannelID, IntPtr hWnd);

(我已经读过c#中的HWND等价物是IntPtr,但我也试过把int,long,object ... ...

我也尝试按以下方式执行DllImport(正如一些帖子中所建议的那样,我正在使用其他一些方法):

[DllImport("dhnetsdk.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]

无论我尝试什么,我都会遇到同样的错误。我想念的是什么?如果抛出c ++代码中的内部异常,我会在代码中得到什么样的异常?

2 个答案:

答案 0 :(得分:0)

#define LLONG   LONG

现在,LONG映射到long,这是Windows上带签名的32位类型。因此,在C#代码中使用long是错误的,因为C#long是64位类型。您需要使用int代替。像这样:

[DllImport("dhnetsdk.dll")]
public static extern int CLIENT_RealPlay(int lLoginID, int nChannelID, IntPtr hWnd);

答案 1 :(得分:-1)

使用调用约定stdcall声明c ++函数,但是使用cdecl调用它。

根据我的经验,调用堆栈损坏主要是由于使用错误的调用约定引起的。