【问题标题】:GCC compiling a dll with __stdcallGCC 使用 __stdcall 编译 dll
【发布时间】:2010-09-11 13:48:28
【问题描述】:

当我们在 Visual Studio 2008 中使用 __stdcall 编译 dll 时,dll 中的编译函数名称是。

函数名

虽然当我们使用 GCC 使用 wx-dev-cpp 编译相同的 dll 时,GCC 会附加函数具有的参数数量,所以使用 Dependency walker 的函数的名称看起来像。

FunctionName@numberOfParameters 或 == FunctionName@8

如何告诉 GCC 编译器从 dll 中导出的符号中删除 @nn?

【问题讨论】:

    标签: c++ gcc name-decoration


    【解决方案1】:

    __stdcall 通过在开头添加下划线来装饰函数名称,在末尾添加参数的字节数(以@分隔)。

    所以,一个函数:

    void __stdcall Foo(int a, int b);
    

    ...会变成 _Foo@8。

    如果您在 .DEF 文件的 EXPORTS 部分中列出函数名称(未修饰),则导出时未修饰。

    也许这就是区别?

    【讨论】:

    • 感谢roger的回复,原来问题是另一个开发者在项目中放了一个DEF文件。该 DEF 文件告诉链接器在 DLL 中使用的命名约定。这就是为什么即使使用相同的调用约定我们也会得到不同的库名称的原因。解决方案是我们的一位开发人员在为项目创建自己的 DLL 时从头文件中删除了 WINAPI。这导致 Windows Visual Studio 恢复到其默认调用约定 __cdecl (/Gd)。
    【解决方案2】:

    只需在 gcc 命令行上使用-Wl,--kill-at,它会将--kill-at 传递给链接器。

    参考资料:

    【讨论】:

    • 我可以确认,--kill-at 可以与 mingw-w64 工具链一起使用。
    【解决方案3】:

    您还可以将-Wl,--add-stdcall-alias 用于 GCC 中的链接器选项。这将确保两个函数名称(装饰和未装饰)都存在并且可以用作别名。

    【讨论】:

    • 感谢 Matthias 不知道这一点。
    猜你喜欢
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-10
    相关资源
    最近更新 更多