Dll Dumpbin显示奇怪的方法名称(在MS Visual C++中生成导出函数)

Dll Dumpbin显示奇怪的方法名称(在MS Visual C++中生成导出函数),dll,pinvoke,dllexport,dumpbin,cdecl,Dll,Pinvoke,Dllexport,Dumpbin,Cdecl,我已经在我的VS中创建了新的Win32项目,并为此选择了动态库*.dll 我在主文件中定义了一些导出功能: __declspec(dllexport) int TestCall(void) { int value = 4 / 2; std::cout << typeid(value).name() << std::endl; return value; } __declspec(dllexport) void SwapMe(int *first,

我已经在我的VS中创建了新的Win32项目,并为此选择了动态库*.dll

我在主文件中定义了一些导出功能:

__declspec(dllexport)
int TestCall(void)
{
    int value = 4 / 2;
    std::cout << typeid(value).name() << std::endl;
    return value;
}

__declspec(dllexport)
void SwapMe(int *first, int *second)
{
    int tmp = *first;
    *first = *second;
    *second = tmp;
}
我是这样调用C版本的:

[DllImport(@"lib1.dll", EntryPoint = "?TestCall@@YAHXZ",
CallingConvention = CallingConvention.Cdecl)]
static extern int TestCall();

这不是使用导出方法的正确形式。在C++的DLL项目中生成导出方法的名称时,我在哪里失败?

< P>使用ExtEngCt指定链接以避免名称的窜改:

extern "C" __declspec(dllexport) int TestCall(void);
extern "C" __declspec(dllexport) void SwapMe(int *first, int *second); 

使用extern C指定链接以避免名称混乱:

extern "C" __declspec(dllexport) int TestCall(void);
extern "C" __declspec(dllexport) void SwapMe(int *first, int *second); 

这是正常的,C++编译器将名称修饰应用到函数中。C++语言支持函数重载,很像C语言。所以你可以写一个Fooint和一个fooduble函数。显然,它们不能都作为名为Foo的函数导出,客户机代码不知道调用哪个函数。因此,额外的字符对名称进行编码,使其对于重载是唯一的

您可以通过声明函数extern C来关闭它,因为C语言不支持重载,所以不需要相同的修饰


但如果你不这样做,事实上会更好。因为这也是一个发现错误的好方法。比如改变C++代码中的函数声明,而忘记修改C代码中的pJoNKE声明。现在,您将得到一个易于诊断的入口点未找到异常,而不是一个非描述性且很难诊断的AccessViolationException异常。它不一定必须在C++代码中被提升,堆栈不平衡也会破坏C代码。查找修饰的名称有点痛苦,但是通过请求链接器创建一个映射文件/映射选项来改善它。

< P>这是正常的,C++编译器将名称修饰应用到函数中。C++语言支持函数重载,很像C语言。所以你可以写一个Fooint和一个fooduble函数。显然,它们不能都作为名为Foo的函数导出,客户机代码不知道调用哪个函数。因此,额外的字符对名称进行编码,使其对于重载是唯一的

您可以通过声明函数extern C来关闭它,因为C语言不支持重载,所以不需要相同的修饰

但如果你不这样做,事实上会更好。因为这也是一个发现错误的好方法。比如改变C++代码中的函数声明,而忘记修改C代码中的pJoNKE声明。现在,您将得到一个易于诊断的入口点未找到异常,而不是一个非描述性且很难诊断的AccessViolationException异常。它不一定必须在C++代码中被提升,堆栈不平衡也会破坏C代码。但是,查找修饰名称有点痛苦,请通过请求链接器创建映射文件/映射选项来改进这一点