6

我正在编写一个可执行文件,它使用 dlopen()(Windows 上的 LoadLibrary())来动态加载共享库。共享库使用可执行文件中的符号。

在 Windows 中这是可能的。可执行文件可以导出符号:declspec(dllexport) 和 .def 文件都可以。链接器在创建 .exe 时也会创建 .lib 文件(“导入库”),因此 DLL 只需与该 .lib 链接即可。

在 Linux 中,这也是可能的。我在构建可执行文件时通过 -Wl,-export_dynamic 以便导出其符号。

相反,在 Mac OS X 上... -Wl,-export_dynamic 不起作用,但有 -Wl,-exported_symbols_list,<filename>其中<filename>是要导出的符号列表(一种更简单的 .def 文件版本)。但是,构建共享库并不容易:链接器抱怨未解析的符号。

我尝试了一个技巧:将可执行文件重命名为 lib <executable>.dylib ,并且在链接共享库时,我通过了 -l <executable>。但它给出了错误“无法与主可执行文件链接”。

一般的问题是 Linux 共享库可以有未解析的符号,而 Windows 和 Mac OS X 不允许。但是 Windows 有“导入库”来解决依赖关系的符号,而 Mac OS X 显然没有......

如何在 Mac OS X 上解决这个问题?是否有等效的“导入库”(Windows 链接器在创建 .dll 时创建的存根库,因此,如果任何模块需要动态链接到 .dll,则它与“导入库”链接)?还是其他解决方案?

4

2 回答 2

5

独立的 Lua 解释器支持动态加载(通过 dlopen)使用来自可执行文件(Lua API)的符号的共享库。构建它时没有使用特殊的链接标志。共享库是使用以下咒语构建的:

env MACOSX_DEPLOYMENT_TARGET=10.3 gcc -bundle -undefined dynamic_lookup -o random.so lrandom.o
于 2010-10-18T13:08:05.017 回答
4

谢谢,您的回答激发了研究bundles和dylibs之间区别的欲望。ld 的手册页提到了一个名为 -bundle_loader 的选项

-bundle_loader executable
这指定了将加载被链接的捆绑输出文件的可执行文件。捆绑包中未定义的符号将根据指定的可执行文件进行检查,就像它是捆绑包所链接的动态库之一一样。

(请注意 -bundle_loader 在构建 dylib 时失败,它仅适用于捆绑包)所以旧的命令行

cc -shared -o <output>.so <input>.c

变成了

cc -bundle -bundle_loader <executable> -o <output>.so <input>.c

并且输出包将其未定义的符号解析为可执行文件。

于 2010-10-18T21:40:46.187 回答