2010-10-17 83 views
6

我正在寫一個使用dlopen()(Windows上的LoadLibrary())來動態加載共享庫的可執行文件。共享庫使用可執行文件中的符號。Mac:如何從可執行文件導出符號?

在Windows中,這是可能的。可執行文件可以導出符號:declspec(dllexport)和.def文件都可以使用。鏈接器在創建.exe時還會創建.lib文件(「導入庫」),因此該DLL只需與該.lib鏈接即可。

在Linux中,這也是可能的。構建可執行文件時,我傳遞-Wl,-export_dynamic,以便導出它的符號。

在Mac OS X,而不是...輪候冊,-export_dynamic不起作用,但輪候冊,-exported_symbols_list,<filename>其中<filename>是符號導出列表(排序的一個簡化版本.def文件)。但是,建立共享庫並不容易:鏈接器抱怨未解決的符號。

我試過一個黑客:將可執行文件重命名爲lib <executable> .dylib,並且在鏈接共享庫時,我通過了-l <executable>。但它給出的錯誤「無法與主可執行文件鏈接」。

一般問題是Linux共享庫可能有未解析的符號,而Windows和Mac OS X不允許它。但Windows有「導入庫」來解決依賴關係的符號,而Mac OS X顯然不...

這怎麼能解決在Mac OS X上?是否有相當於一個「導入庫」(創建.dll時由Windows鏈接器創建的存根庫,因此,如果有任何模塊需要動態鏈接到.dll,它與「導入庫」鏈接)?或者其他解決方案?

回答

5

獨立的Lua解釋器支持動態加載(通過dlopen)使用可執行文件(Lua API)中的符號的共享庫。構建時不使用特殊鏈接標誌。共享庫建成使用此咒語:

env MACOSX_DEPLOYMENT_TARGET=10.3 gcc -bundle -undefined dynamic_lookup -o random.so lrandom.o 
+1

順便提一下,10.5和更高版本不需要「env MACOSX_DEPLOYMENT_TARGET = 10.3」。 – lhf 2011-01-18 21:31:57

4

謝謝你,你的回答刺激調查束和dylibs之間的差別的願望。和LD的手冊頁提到的所謂-bundle_loader

選項-bundle_loader可執行
此規定將被加載束 輸出文件被鏈接的可執行文件。將根據指定的可執行文件檢查包 中的未定義符號,就像它是該包所鏈接的動態庫的一個 一樣。

(注意,構建一個dylib時-bundle_loader失敗,則只能用捆綁的作品) 所以舊的命令行

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

被闢爲

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

和輸出束根據可執行文件解析了未定義的符號。