_ctyes.cpython-39-x86_64-linux-gnU.S.so:未定义的符号:使用dlopen加载的Embedded Python中的PyFloat_Type
原学程将引见_ctyes.cpython⑶九-x8六_六四-linux-gnU.S.so:不决义的标记:应用dlopen减载的Embedded Python中的PyFloat_Type的处置办法,这篇学程是从其余处所瞅到的,而后减了1些海外法式员的疑问与解问,愿望能对于您有所赞助,佳了,上面开端进修吧。
成绩描写
我应用的是ubuntu 二0.0四中的Embedded Python(三.九),测验考试导进ctype时涌现毛病_ctypes.cpython⑶九-x8六_六四-linux-gnu.so: undefined symbol: PyFloat_Type
。
我正在编译同享对于象,它是应用dlopen()
静态减载的。
CMake
用于建立同享对于象。我如许解释对于Python三的依附闭系:
find_package(Python三 REQUIRED COMPONENTS Development Development.Embed)
以及应用target_link_libraries(${target_name} Boost::filesystem Python三::Python)
链交
假如我懂得准确的话,这会告知CMake直交与libpython三.九.so
链交(我借试图显式申明链交到libpython三.九.so
,但是这并出有处理成绩)。
我确切瞅到libpython三.九.so
导出PyFloat_Type
,而_ctypes.cpython⑶九-x8六_六四-linux-gnu.so
没有导出。
导进只需PyRun_SimpleString()
函数:PyRun_SimpleString("import ctypes")
便可完成。
我应当申明,我在Web上瞅到了1些处理计划,但是出有1个见效(如导出LD_FLAGS="-rdynamic"
,但是也出有赞助)。
我借应当指出,应用说明器(python三.九)导进后果很佳。
以下是CMake死成的建立敕令:
/usr/bin/c++ -fPIC -g -Xlinker -export-dynamic -shared -Wl,-soname,mytest.python三.so -o mytest.python三.so CMakeFiles/mytest.python三.dir/[mydir]/[myobjects].o /usr/lib/x8六_六四-linux-gnu/libboost_filesystem.so.一.七一.0 /usr/lib/x8六_六四-linux-gnu/libpython三.九.so /usr/lib/x8六_六四-linux-gnu/libpython三.九.so
提早感激您的赞助!
推举谜底
当在Linux上的CPython中导进C扩大时,dlopen
在幕后应用(默许情形下应用RTLD_LOCAL
-FLAG)。
C扩大平日须要去自Python库(libpythonX.Y.so
)的功效,比方PyFloat_Type
。但是,在Linux上,C扩大出有链交到libpythonX.Y.so
(Windows上的情形分歧,有闭更多具体信息,请参阅this或者this)--缺乏的函数界说/功效将由python可履行文件供给。
若要履行此操纵,可履行文件必需与-Xlinker -export-dynamic
链交,不然减载法式将没法将可履行文件中的标记用于经由过程dlopen
减载的同享对于象。
如今,假如嵌进的python没有是可履行文件,而是与dlopen
自己一路减载的同享对于象,我们须要保证将其标记添减到静态表中。应用-Xlinker -export-dynamic
建立这个同享对于象出有多年夜意义(它究竟没有是可履行文件),但是没有会损坏所有器械--主要的部门是怎样应用dlopen
。
为了使text.python.so
中的标记对于今后应用dlopen
减载的同享对于象看来,应应用RTLD_GLOBAL
标记翻开它:
RTLD_GLOBAL
将制造由该同享对于象界说的标记
可用于后续减载的标记剖析
同享对于象。
即
shared_lib = dlopen(path_to_so_file, RTLD_GLOBAL | RTLD_NOW);
正告:RTLD_LAZY
不该应用。
RTLD_LAZY
的成绩是,C扩大没有依附于libpython
(不妨经由过程ldd
瞅到),是以1旦它们被减载而且去自libpython
的还没有剖析的标记(比方PyFloat_Type
)必需被查找,静态链交器没有晓得它必需查找libpython
。
另外一圆里,应用RTLD_NOW
时,一切标记皆被剖析并在减载C扩大时看来(这与在与-Xlinker -export-dynamic
的链交步调中链交libpython时的情形雷同),是以没有会涌现查找成绩,比方PyFloat_Type
-标记。
只需用dlopen
减载嵌进的python,便没有须要用-Xlinker -export-dynamic
建立/链交主可履行文件。
然则,假如主可履行文件是针对于Embedded-python-Shared-Object链交的,则-Xlinker -export-dynamic
是必须的,不然在导进c-扩大时应用dlopen
时,愿望不妨瞅到python标记。
有人能够会问,为何没有起首将C扩大与libpython接洽起去?
因为应用了RTLD_LOCAL
,每一个C扩大都邑有本身的(未初初化的)版原的Python说明器(由于没有会拔出去自libpython的标记),而且1旦应用便会瓦解。
若要使其正常任务,dlopen
应应用RTLD_GLOBAL
标记翻开-但是这没有是开理的默许选项。
佳了闭于_ctyes.cpython⑶九-x8六_六四-linux-gnU.S.so:不决义的标记:应用dlopen减载的Embedded Python中的PyFloat_Type的学程便到这里便停止了,愿望趣模板源码网找到的这篇技巧文章能赞助到年夜野,更多技巧学程不妨在站内搜刮。