可能重复:
A call to PInvoke function '[…]' has unbalanced the stack
我正在尝试包装一些用c ++编写的函数,以便在c#程序中使用它们(WPF,或者作为一个控制台应用程序的示例),但是获得运行时异常。
我想这是一个编译问题(C#one的c ++项目)。当我更改C#项目的平台目标时,我得到了不同的例外。当平台目标是x64我得到
尝试加载格式不正确的程序。 (HRESULT异常:0x8007000B)
当我尝试将其编译为x86时,我得到:
对PInvoke函数'Wrapper!Wrapper.IWrapper :: create'的调用使堆栈失衡。这很可能是因为托管PInvoke签名与非托管目标签名不匹配。检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。
我在Windows 7 64上运行VS2010。
对于如何解决这个问题的任何想法都会感到高兴。
c ++代码。 CPP:
int create(int Handle)
{
return 1;
}
和h:
#define EXPORT_DLL __declspec(dllexport)
extern "C"
{
EXPORT_DLL int create(int Handle);
}
然后在第二个C#项目中,我调用这个dll,其中c ++项目的名称是wrapAttemptC
namespace Wrapper
{
internal class IWrapper
{
const string SHADOW_DLL_NAME = "wrapAttemptC.dll";
[DllImport(SHADOW_DLL_NAME)]
public static extern int create(int Handle);
}
public class CWW
{
public CWW(){}
public int Connect(int cam)
{
return IWrapper.create(cam);
}
}
}
然后,我将c ++项目中创建的DLL文件放在此c#项目的bin / Debug和app c#project(WPF)中,并尝试调用
CWW cww = new CWW();
cww.Connect(5);
答案 0 :(得分:2)
C ++导出函数的默认调用约定为cdecl
,但DllImport
属性的默认调用约定为WinApi
(默认为stdcall
)。所以你在那里有一个不匹配,可能会弄乱你的堆栈。尝试在DllImport
属性,C ++函数声明或更好的两者中明确地声明调用约定(以便它们匹配)。像这样:
EXPORT_DLL __stdcall int create(int Handle);
在你的C#项目中:
[DllImport(SHADOW_DLL_NAME, CallingConvention = CallingConvention.StdCall)]