在 C# 中调用 C++ dll 时无法找到入口点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10109590/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unable to find an entry point when calling C++ dll in C#
提问by King Chan
I am trying to learn P/Invoke, so I created a simple dll in C++
我正在尝试学习 P/Invoke,所以我在 C++ 中创建了一个简单的 dll
KingFucs.h:
KingFucs.h:
namespace KingFuncs
{
class KingFuncs
{
public:
static __declspec(dllexport) int GiveMeNumber(int i);
};
}
KingFuns.cpp:
KingFuns.cpp:
#include "KingFuncs.h"
#include <stdexcept>
using namespace std;
namespace KingFuncs
{
int KingFuncs::GiveMeNumber(int i)
{
return i;
}
}
So it does compile, then I copied this dll into my WPF's debug folder, with code:
所以它确实编译了,然后我将这个 dll 复制到我的 WPF 的调试文件夹中,代码如下:
[DllImport("KingFuncDll.dll", EntryPoint = "GiveMeNumber", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern int GiveMeNumber(
int i
);
And calling it in button click:
并在按钮单击中调用它:
private void Button_Click(object sender, RoutedEventArgs e)
{
int num = GiveMeNumber(123);
}
But it gives me exception:
但它给了我例外:
Unable to find an entry point named 'GiveMeNumber' in DLL 'KingFuncDll.dll'.
无法在 DLL“KingFuncDll.dll”中找到名为“GiveMeNumber”的入口点。
Really.... what have I done wrong... It obviously able to find the DLL, otherwise would be another exception. But my method name is exactly the same.... I can't think of other reason.
真的......我做错了什么......它显然能够找到DLL,否则将是另一个例外。但是我的方法名称完全一样......我想不出其他原因。
采纳答案by David Heffernan
You need to use extern "C"when you export your function so that you suppress C++ name mangling. And you also should not try to p/invoke to members of a class. Use free functions instead:
您需要extern "C"在导出函数时使用,以便抑制 C++ 名称修饰。而且您也不应该尝试对类的成员进行 p/invoke。改用免费函数:
extern "C" {
__declspec(dllexport) int GiveMeNumber(int i)
{
return i;
}
}
On the managed side your DllImportattribute is all wrong. Don't use SetLastErrorwhich is for Win32 APIs only. Don't bother setting CharSetif there are not text parameters. No need for ExactSpelling. And the calling convention is presumably Cdecl.
在托管方面,您的DllImport属性完全错误。不要使用SetLastError仅用于 Win32 API 的。CharSet如果没有文本参数,请不要打扰设置。不需要ExactSpelling。调用约定大概是Cdecl.
[DllImport("KingFuncDll.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern int GiveMeNumber(int i);
回答by Pedro
The problem is that you are declaring the C++ "function" inside a C++ class and are telling P/Invoke to use StdCall.
问题是您在 C++ 类中声明了 C++“函数”,并告诉 P/Invoke 使用 StdCall。
Try to declare a C++ function outside a class and and export it like you did. Then your code should work.
尝试在类外声明一个 C++ 函数,然后像您一样导出它。那么你的代码应该可以工作。
If you really must have a C++ function inside a class, take a look at CallingConvention.ThisCall. But then you are responsible for creating your unmanaged class instance and pass it as the first parameter of your P/Invoke call
如果您确实必须在类中使用 C++ 函数,请查看 CallingConvention.ThisCall。但是随后您负责创建非托管类实例并将其作为 P/Invoke 调用的第一个参数传递
回答by MetallicLord Shivam
The entry point name of a dll file is given in .exp file which is found in debug folder where other source files are present. If dumpbin doesn't work you can try this.
dll 文件的入口点名称在 .exp 文件中给出,该文件位于存在其他源文件的调试文件夹中。如果 dumpbin 不起作用,你可以试试这个。

