我正在尝试学习P / Invoke,所以我在C ++中创建了一个简单的dll
KingFucs.h:
namespace KingFuncs
{
class KingFuncs
{
public:
static __declspec(dllexport) int GiveMeNumber(int i);
};
}
KingFuns.cpp:
#include "KingFuncs.h"
#include <stdexcept>
using namespace std;
namespace KingFuncs
{
int KingFuncs::GiveMeNumber(int i)
{
return i;
}
}
所以它编译,然后我将这个dll复制到我的WPF的调试文件夹中,代码为:
[DllImport("KingFuncDll.dll", EntryPoint = "GiveMeNumber", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern int GiveMeNumber(
int i
);
按下按钮点击它:
private void Button_Click(object sender, RoutedEventArgs e)
{
int num = GiveMeNumber(123);
}
但它给了我例外:
无法在DLL中找到名为“GiveMeNumber”的入口点 'KingFuncDll.dll'。
真的....我做错了什么......显然能找到DLL,否则会是另一个例外。但我的方法名称完全一样......我想不出其他原因。
答案 0 :(得分:33)
导出函数时需要使用extern "C"
,以便抑制C ++名称修改。而且你也不应该尝试p / invoke给一个类的成员。请改用免费功能:
extern "C" {
__declspec(dllexport) int GiveMeNumber(int i)
{
return i;
}
}
在托管端,您的DllImport
属性完全错误。不要仅使用适用于Win32 API的SetLastError
。如果没有文本参数,请不要设置CharSet
。无需ExactSpelling
。调用约定大概是Cdecl
。
[DllImport("KingFuncDll.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern int GiveMeNumber(int i);
答案 1 :(得分:0)
问题是你在C ++类中声明了C ++“function”并告诉P / Invoke使用StdCall。
尝试在类之外声明一个C ++函数,然后像你一样导出它。那么你的代码应该可以工作。
如果你真的必须在一个类中有一个C ++函数,请看看CallingConvention.ThisCall。但是,您负责创建非托管类实例并将其作为P / Invoke调用的第一个参数传递
答案 2 :(得分:0)
dll文件的入口点名称在.exp文件中给出,该文件位于调试文件夹中,其中存在其他源文件。如果dumpbin不起作用,你可以尝试这个。