4

我正在尝试构建一个用 C 编写的 dll,它将由其他也用 C 编写的程序导入。

因此,dll 正在导出的所有函数都在 .dll 中定义,“没有 __declspec(dllexport)”(有意)。我已经定义了一个 .def 文件,其中只有一个导出部分和我要导出的函数的名称(未损坏的名称)。

我正在使用 vc71/vs2003 来构建它,但我仍然得到错误的名称(如果我在记事本中打开 .lib 可以看到)。同样为了澄清起见,Visual Studio 也会导致 C 代码中的名称混淆(我能找到的大多数资源都提到它是仅 C++ 的问题)。

我怎样才能防止这个名字被篡改?

更多的信息:

错位名称的格式为“functionName@integer”,其中整数表示以字节为单位的参数大小(而不是序数)。例如,

来自 .lib: _PrepareSeverResponse@8

.h 中的函数声明: char* PrepareSeverResponse(unsigned int* size ,handshake* ws_handshake);

.def: 导出 PrepareSeverResponse

调用约定: __stdcall(/Gz)

希望这能让它更清楚。

4

4 回答 4

6

将调用约定更改为 cdecl 对我有用。extern "C" 解决方案对我没有太大帮助,因为在我的情况下,问题在于编译 .C 文件时的名称修改,好像我理解正确,extern "C" 解决方案用于在编译 cpp 时抑制名称修改文件。

于 2011-11-04T10:41:53.953 回答
2

为了防止名称混淆,您需要用以下内容包装标题extern C

#ifdef __cplusplus
extern "C" {
#endif


//  Headers


#ifdef __cplusplus
}
#endif

这将强制符号使用它们的 C 样式(未损坏)名称。

于 2011-11-03T07:12:06.357 回答
2

您看到的名称 mangling 与 C++ 无关;它是 Microsoft 的调用约定名称装饰,也适用于 C 代码。您可以在 .DEF 文件中为这些名称取别名:

EXPORTS
  PrepareServerResponse=_PrepareSeverResponse@8
  _PrepareSeverResponse@8

请注意,当您将库链接到另一个程序时,主机程序将寻找修饰名称。您可能需要一个未修饰名称的主要情况是,如果您希望用户使用LoadLibrary和加载您的 DLL GetProcAddress

于 2011-11-04T06:15:52.207 回答
0

在没有看到您将其描述为“名称修改”的情况下,我猜您必须将 Visual Studio 设置为Compile as C Code (/TC).

它在Properties->C/C++->Advanced->Compile As。您可以为整个项目选择此设置,因为这是您的意图。

于 2011-11-03T16:41:36.877 回答