2009-12-19 61 views
7

我正在維護一個small application,它具有一些類似插件的功能,它通過運行時加載的動態模塊實現。從OS X上的dlopen()ed動態庫訪問主程序全局變量

具體而言,因爲它是一個Gtk +應用程序,所以我使用gmodule,但問題也適用於基於dlfcn.h/dlopen()的動態庫加載。

我的主程序有一個保存一些全局信息的單個全局結構體變量。我希望這些信息可用於動態加載插件中定義的函數。

在Linux上,我可以直接引用這個全局變量 - 這很好,我猜測gcc或鏈接器負責將全局變量從主程序導出到動態庫。

問題是,這不適用於Mac OS X.有沒有辦法在OS X上做到這一點?

如果沒有,是否有更多的「最佳實踐」的方式來暴露全球信息動態加載庫?

+0

順便說一句,這裏有一些簡化問題的示例代碼:http://pastie.org/749794 – shevron 2009-12-19 18:00:05

回答

10

把全球main.c中,並在共享對象的extern聲明它,試試這個:

MACOSX_DEPLOYMENT_TARGET=10.3 ld -dylib -undefined dynamic_lookup -o multiply.so multiply.o 

MACOSX_DEPLOYMENT_TARGET=10.3 libtool -dynamic -undefined dynamic_lookup -o multiply.so multiply.o 

它爲我工作在Mac OS X 10.4

+0

謝謝,這個作品!雖然我沒有使用TAGET環境變量,但我猜這是不太相關的。現在看看如何將這個集成到我的Makefiles中! – shevron 2009-12-19 20:45:51

+0

它也可以工作目錄gcc: gcc -Wall -g -fPIC -c multiply.c gcc -shared -Wl,-undefined,dynamic_lookup -o multiply.so multiply.o – shevron 2009-12-19 20:50:52

3

既然你聲明

int global; 
在multiply.h頭

,DLL和主程序都有自己的副本它。相反,宣告全球main.c中

int global; 

和multiply.c聲明它爲外部:

extern int global; 

現在,如果你用-rdynamic選項鍊接main.cpp中,然後可執行文件的符號將被導出到DLL。我在Linux下測試了它,它工作正常,但我恐怕沒有權限訪問MacOS上的測試。既然你的ssample代碼也不能在linux上工作,我預計這是個問題。

+0

AFAIK -rdynamic在OS X上不受支持。無論如何,我在嘗試鏈接時遇到「_global」未定義的錯誤multiply.o – shevron 2009-12-19 20:46:38