簡體   English   中英

在dlopen打開另一個C庫的Python中加載C庫-未解析的共享符號

[英]Loading C library in Python that dlopens another C library - unresolved shared symbol

我有一個具有多個功能的商業c庫(a.so)。 當您調用a.open()函數時,它將動態地對另一個庫執行dlopen()調用。 如果調用a.open('b'),它將打開b.so。 如果調用a.open('c'),它將打開c.so。

問題是a.so和b.so共享a.so中定義的全局變量,但由b.so(和c.so等)引用。 我能夠使用ctypes在python中正確加載a.so並查看Python中的所有符號。 但是,當我調用a.open('b')時,它將嘗試加載b.so,但返回未定義的符號。

//a.c -source for a.so library
int aglobal = 0;
void open(char* lib)
{ dlopen(lib); }

//b.c - source for b.so library
extern int aglobal;

這是我要加載的python代碼:

from ctypes import cdll
p = ctypes.CDLL('a.so')
p.open('b')

返回錯誤代碼:未定義符號:aglobal

其他注意事項:

  • 文件與-fPIC -rdynamic -shared鏈接

  • 當我編寫一個與python程序功能相同的C程序時,沒有問題。

  • 我還嘗試過swig來包裝庫,以及許多其他東西,構建選項等,但是結果相同。

Python是否以不同的方式綁定符號?

加載a.so時需要使用RTLD_GLOBAL

該對象的符號應可用於任何其他對象的重定位處理。 此外,使用dlopen(0, mode)和關聯的dlsym()進行符號查找允許搜索以該模式加載的對象。

Linux手冊頁更加簡單:

該共享庫定義的符號將可用於后續加載的共享庫的符號解析。

python文檔描述了該選項的存在,但未描述其作用。

2.6版中的新增功能:添加了use_last_error和use_errno可選參數。

ctypes.RTLD_GLOBAL
標記用作模式參數。 在此標志不可用的平台上,它定義為整數零。

ctypes.RTLD_LOCAL
標記用作模式參數。 在此功能不可用的平台上,它與RTLD_GLOBAL相同。

ctypes.DEFAULT_MODE
用於加載共享庫的默認模式。 在OSX 10.3上,這是RTLD_GLOBAL ,否則與RTLD_LOCAL相同。

從文檔看來,您所處的系統上DEFAULT_MODERTLD_LOCAL相同,這與RTLD_GLOBAL相反。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM