-->

DUMPBIN显示奇怪的方法名(生成MS的Visual C导出函数++)(Dumpbin shows

2019-09-29 11:57发布

我在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;
}

当我看了dumpin /出口,我有:

ordinal hint RVA      name

      1    0 00001010 ?SwapMe@@YAXPEAH0@Z
      2    1 00001270 ?TestCall@@YAHXZ

我打电话给在C#的版本是这样的:

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

它不使用导出的方法的正确形式。 我在哪里失败,在C ++ DLL项目出口的方法产生这样的名字?

Answer 1:

这是正常的,C ++编译器应用的名字装饰功能。 C ++语言支持函数重载,就像C#一样。 所以,你可以写一个Foo(int)Foo(double)功能。 显然,他们不能同时导出为一个名为“foo”功能,客户端代码就不知道该调用哪个之一。 因此多余的字符编码的名称,以便它是在过载能力独特。

您可以通过声明函数把它们关掉extern "C" ,C语言不支持重载所以不需要同样的装修。

但是,如果你实际上并不好。 因为它也是发现错误的好方法。 像改变函数的声明在你的C ++代码,但忘记修改你的C#代码的PInvoke的声明。 现在,您将得到一个容易诊断“入口点未找到”的异常,而不是一个非描述性的,非常难以诊断AccessViolationException。 这并不一定必须在C ++代码中提出,堆栈失衡也可能会崩溃你的C#代码。 仰望装饰名字有点痛但是,通过询问链接器创建一个映射文件(/ MAP选项)改进这一点。



Answer 2:

使用外部的“C”,以指定的链接为避免名字改编:

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


文章来源: Dumpbin shows strange method name (generating exporting function in MS Visual C++)