我在MV C ++ 2012中创建了一个DLL,当我使用
时Dumpbin /Exports filename
DLL文件中的函数名称内部具有相同的符号。我不得不使用公共语言运行时支持(/ crl),因为我使用了来自C#的DLL。这是为什么函数的名称会出现等号?我的头文件:
#ifdef ColorDLL_EXPORTS
#define ColorDLL_API __declspec(dllexport)
#else
#define ColorDLL_API __declspec(dllexport)
#endif
extern "C"{
ColorDLL_API int ColorSelect(int i);
}
ColorDLL.cpp
#include "stdafx.h"
#include "ColorDLL.h"
#using <ColorDiologeClass.dll>
extern "C"{
ColorDLL_API int ColorSelect(){
ColorDiologeClass::Class1::ColorReturn(1);
return 1;
}
} 当我使用Dumpbin时,名字显示为:
Name
ColorSelect = _ColorSelect
这是为什么?我希望它显示为ColorSelect,而不是ColorSelect = _ColorSelect。如果我以这种方式离开它,我将如何从像JMP这样需要确切函数名称的程序中调用此函数?它会是ColorSelect吗?或者它是ColorSelect = _ColorSelect?
答案 0 :(得分:0)
名称为“mangled” - 返回类型和参数被编入函数名称。如果您不希望这样,您可以在函数名之前(或在函数块周围)使用extern "C"
。
答案 1 :(得分:0)
这就是名称修改,这是c ++的底层功能,它允许它支持函数重载(因为它将函数的参数类型合并到其名称中)。
答案 2 :(得分:0)
C:\>undname ?ColorSelect@@YAHXZ
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.
Undecoration of :- "?ColorSelect@@YAHXZ"
is :- "int __cdecl ColorSelect(void)"
如果您想在自己的代码中执行相同操作,也可以使用UnDecorateSymbolName
执行此操作。
对于它的价值,装饰/修改不仅支持重载,而且支持typesafe linking。 Typesafe链接源于函数重载虽然它本身并不是真正的函数重载。
具体来说,类型安全链接处理(例如)如何处理具有sqrt
float
,double
,long double
重载的C ++代码,也可能是complex
,但链接到提供double sqrt(double)
但不提供其他重载的C库。在这种情况下,我们通常希望在使用正确的参数时使用它,但不能使用。
即使没有涉及函数重载,也可以(或可能)出现。例如,在纯C中你可以这样做:
#include <stdio.h>
extern int sqrt(int);
// ...
printf("%d", sqrt(100));
现在,我们已经告诉编译器我们正在使用sqrt
版本来获取(并返回)int
。遗憾的是,链接器没有意识到这一点,因此它仍然与标准库中的sqrt
链接并返回double
。因此,上面的代码将打印一些完全无用的结果(通常是0
,而不是很重要)。
Typesafe链接可以防止这种情况 - 即使它不是函数重载,我们仍然有两个具有相同名称的函数,但是在我们链接时它们的类型不同。通过将参数类型编码到名称中,链接器可以像编译器那样将其整理出来。
当我们在不同的库之间发生名称冲突时,C中也会出现同样的情况(并经常出现)。使用传统的C编译器,理顺这种混乱可能非常困难(充其量)。使用C ++编译器,除非两个库不仅使用相同的名称,而且使用相同数量和类型的参数,否则它根本不会成为问题。