DumpBin显示奇怪的方法名称(在MS Visual C 中生成导出功能)



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

当我查看垃圾箱/出口时,我有:

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项目中生成此类名称的我在哪里失败?

这是正常的,C 编译器将名称装饰应用于函数。C 语言支持功能超载,就像C#一样。因此,您可以编写Foo(int)Foo(double)功能。显然,它们都不能以名为" foo"的函数导出,客户代码不知道该拨打哪个函数。因此,额外的字符编码名称,以使其对超载是唯一的。

您可以通过声明函数extern "C",C语言不支持超载,因此不需要相同的装饰。

但是,如果不这样做,那实际上更好。因为这也是捕获错误的绝佳方法。就像更改C 代码中的函数声明一样,但忘记在C#代码中修改PINVOKE声明。现在,您将易于诊断出"未找到的入口点"异常,而不是不描述性,并且很难诊断accessVioLationException。不一定必须在C 代码中提高,堆栈不平衡也可能会使您的C#代码崩溃。查找装饰的名称有点痛苦,但是,通过要求链接器创建地图文件(/地图选项)来改进它。

使用extern" c"指定链接以避免名称mangling:

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

相关内容

  • 没有找到相关文章

最新更新