.def文件相当于OS X

.def file equivalent for OS X

本文关键字:OS 相当于 文件 def      更新时间:2023-10-16

我发现了一种有趣的方法,可以使用模块定义(.def)文件和友好的导出名称从dll(windows)导出函数,但我找不到任何关于如何在Mac上实现这一点的信息。

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

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

使用.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>项有点混乱,表示参数所需的字节数。CCD_ 19调用约定添加了这一点以确保调用方理解被调用的函数在返回之前将从堆栈弹出该数量的字节,这样调用方就可以为函数调用清除任何可能的额外参数(这只是理论上的——编译器会自动将varadic例程转换为cdecl调用约定,以在默认情况下消除此问题)
其他平台上的ABI不使用调用约定,该约定可以像那样在调用者和被调用者之间分配堆栈清理的责任,因此,默认情况下,为了"保护",不会出现这样的混乱。