将外部依赖项添加到C ++ DLL文件

时间:2013-05-31 22:21:23

标签: c# c++ cmd

我在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?

3 个答案:

答案 0 :(得分:0)

名称为“mangled” - 返回类型和参数被编入函数名称。如果您不希望这样,您可以在函数名之前(或在函数块周围)使用extern "C"

答案 1 :(得分:0)

这就是名称修改,这是c ++的底层功能,它允许它支持函数重载(因为它将函数的参数类型合并到其名称中)。

Here's another question更详细。

答案 2 :(得分:0)

微软称之为“装饰”而非破坏。它们包括一个名为“undname”的命令行工具,它将从装饰名称中生成原始名称:

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 floatdoublelong 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 ++编译器,除非两个库不仅使用相同的名称,而且使用相同数量和类型的参数,否则它根本不会成为问题。