Jen*_*nix 1 c# c++ pinvoke calling-convention stdcall
我创建了一个DLL文件,其中包含两个空函数.
extern "C" __declspec(dllexport) void __stdcall myFunc1() {
// just empty function
}
extern "C" __declspec(dllexport) void __cdecl myFunc2() {
// just empty function
}
Run Code Online (Sandbox Code Playgroud)
在C#中,我可以使用DLLImport如下属性调用函数.
[DllImport("myDLL", CallingConvention=CallingConvention.StdCall)]
private extern static void myFunc1();
[DllImport("myDLL", CallingConvention=CallingConvention.Cdecl)]
private extern static void myFunc2();
Run Code Online (Sandbox Code Playgroud)
所以我再次尝试使用LoadLibrary()kernel32.dll而不是DllImport属性.
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate void MyFunc1();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void MyFunc2();
Run Code Online (Sandbox Code Playgroud)
但是,当我调用MyFunc1()工作时MyFunc1()时会发生运行时错误.
所以我__stdcall用__cdeclC++ 替换,重新编译DLL,然后在C#中再次调用MyFunc1().
并且......它奏效了.
为什么地球上没有__stdcall呼叫约会在C#中用pinvoke工作?
这里发生的是当您从C++代码切换__cdecl到__stdcallC++代码时,编译器会修饰导出函数的名称.而不是将myFunc1其导出为myFunc1@0或可能_myFunc1@0.同样,名字是装饰的.你可以使用dumpbinDependency Viewer 来检查是这样的.
当你调用时GetProcAddress,它找不到一个名为的函数myFunc1,所以返回NULL.您不检查返回值,因此无论如何都要继续.当您尝试调用该函数时,将引发运行时错误.
我不得不猜测大部分内容,因为你没有显示完整的代码.另一个重要的教训是在调用Win32函数时检查错误.