【问题标题】:.def file equivalent for OS X.def 文件等效于 OS X
【发布时间】:2016-04-27 20:08:47
【问题描述】:

我发现了一种有趣的方法,即使用模块定义 (.def) 文件和友好名称从 dll (windows) 导出函数,但我找不到任何有关如何在 Mac 上完成此操作的信息.

我想知道 OS X 上是否有任何等效的模块定义。

【问题讨论】:

标签: c++ macos dllimport dylib dllexport


【解决方案1】:

您正在寻找的主要部分(如果我理解的话)可以使用链接器 (ld) 的 -alias <symbol_name> <alternate_symbol_name>-alias_list <filename> 选项来完成。您可以使用-exported_symbol <symbol>-unexported_symbol <symbol> 以及它们的文件列表对应项-exported_symbols_list <filename>-unexported_symbols_list <file> 来实现额外的控制。

【讨论】:

    【解决方案2】:

    使用 .def 文件对导出的符号强制使用更简单的命名约定 真的 不是要走的路 - 通常,一旦您在该级别遇到问题,很有可能会出现其他问题出错。我基于您问题中的C++ 标签。

    通常,如果您打算连接C++ 代码,编译器/链接器将生成正确的修改以匹配您要导出的代码,这样当您尝试使用它时,链接器错误将表明您偏离了二进制兼容性和链接可能是您的问题中最少的 - 你们都误入了潜在不兼容的分配器等。

    您应该导出一个简单的“C”api,这将减少链接的复杂性 - 有一个明确定义的 C 链接,并且例程将获得简单的链接名称。

    这是 .h 文件中守卫的一般用途:

    #ifdef __cplusplus
    extern "C" {
    #endif
    
    … library exports …
    
    #ifdef __cplusplus
    }
    #endif
    

    这将自动为您提供比在尝试链接 C++ 代码时通常会看到的卷积更简单的链接名称 - 只要您在编译 .cpp 文件时 #include .h 文件,如只要在.h 中有您要导出的例程的声明,并且在.cpp 中有相应的定义,它们就会被自动导出。

    您仍然可以使用 Ken Thomases 答案提供的答案 - 它们将为您提供符号可见性和符号别名,但是 TBH,听起来您正在尝试将您一直在 Windows 中使用的解决方案适应另一个平台,但在我看来,您似乎一开始就在 Windows 平台中使用了不正确的方法。

    历史/联动评论:

    我还要提一下,Windows 上的 .def 文件支持实际上是由 Windows 上不同的导出机制引起的 - 它最初按序号从 .dll 文件中导出符号 - 即你必须使用的数字def 文件将名称的链接重新映射回有问题的数字,以便理解诸如调用约定之类的东西。大多数 unix/linux 系统从不只导出编号索引,这意味着 API 中定义的名称可以直接链接。
    现在,从 Windows .dll 文件导出的函数名称末尾的 @<number> 项稍显混乱,表示参数所需的字节数。 __stdcall 调用约定添加了这一点,以确保调用者理解被调用的函数将在返回之前从堆栈中弹出该数量的字节,以便调用者可以清理函数调用的任何可能的额外参数(这只是理论上的 - 可变参数例程由编译器自动转换为 cdecl 调用约定,以默认消除此问题。
    其他平台上的 ABI 不使用调用约定,这样可以在调用者和被调用者之间分摊清理堆栈的责任,因此,默认情况下,不要为了“保护”而进行那样的修改。

    【讨论】:

    • 感谢您的详细回答,我肯定需要重新考虑我的一些方法。我将 Ken Thomases 的答案标记为已接受以用于跟踪目的,因为它直接回答了问题,但你的答案非常有帮助,让我思考我所做的事情。
    猜你喜欢
    • 2016-02-18
    • 2015-05-05
    • 2010-10-04
    • 2013-06-13
    • 2011-03-26
    • 2012-06-06
    • 2020-01-19
    • 2010-11-29
    • 2010-09-05
    相关资源
    最近更新 更多