#python #c #pybind11
#python #c #pybind11
Вопрос:
У меня есть два модуля расширения, образно названные foo
и bar
. bar
состоит из функции C и простой оболочки вокруг нее
#include <pybind11/pybind11.h>
int add_numbers(int a, int b)
{
return a b;
}
int bar_add_numbers(int a, int b)
{
return add_numbers(a, b);
}
PYBIND11_MODULE(_bar, m)
{
m.def("add_numbers", amp;bar_add_numbers);
}
foo
имеет идентичную оболочку, но без определения.
#include <pybind11/pybind11.h>
int add_numbers(int, int);
int foo_add_numbers(int a, int b)
{
return add_numbers(a, b);
}
PYBIND11_MODULE(_foo, m)
{
m.def("add_numbers", amp;foo_add_numbers);
}
После сборки их с помощью setuptools
import os
from setuptools import setup, Extension
import pybind11
os.environ['CC'] = 'clang '
os.environ['CXX'] = 'clang '
libbar = Extension('foo._bar',
sources = ['bar.cpp'],
extra_compile_args=['-std=c 14'],
include_dirs = [pybind11.get_include()]
)
libfoo = Extension('foo._foo',
sources = ['foo.cpp'],
extra_compile_args=['-std=c 14'],
include_dirs = [pybind11.get_include()]
)
setup(name='foo',
version='1.0.0',
ext_modules = [libbar, libfoo]
)
мое ожидание (надежда) заключалось в том, что, если foo._foo
оно было импортировано после foo._bar
, тогда add_numbers
оно должно быть правильно разрешено из любой оболочки. Похоже, это имеет место в OSX.
>>> from foo import _bar
>>> from foo import _foo
>>> _foo.add_numbers(40, 2)
42
Однако в окне ubuntu это не удается undefined symbol: _Z11add_numbersii
. И как раз тогда, когда я подумал, что у меня могут быть почти рабочие знания о динамическом связывании.
Что мне нужно сделать по-другому в Linux (или, более конкретно, в дистрибутивах на основе debian), чтобы это заработало?
РЕДАКТИРОВАТЬ: вывод из nm
двух файлов .so
$ nm _bar.cpython-37m-x86_64-linux-gnu.so | grep "add_numbers"
0000000000004a50 T _Z11add_numbersii
0000000000004a60 T _Z15bar_add_numbersii
и
$ nm _foo.cpython-37m-x86_64-linux-gnu.so | grep "add_numbers"
U _Z11add_numbersii
00000000000048c0 T _Z15foo_add_numbersii
И fwiw флаги компилятора
clang -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-Bsymbolic-functions -Wl,-z,relro -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2
Комментарии:
1. Если у вас одно и то же имя (например, «add_numbers») в двух разных, но одновременных библиотеках, какую из них можно использовать?
2.
add_numbers
определяется только один раз.3. Чтобы было немного понятнее, символ
_Z11add_numbersii
определяется (в данном случае) в модуле расширения_bar.cpython-37m-x86_64-linux-gnu.so
. Я ожидал, что как только интерпретатор python загрузит этот модуль, функция может быть вызвана из другого модуля расширения. Похоже, это работает на OSX, но не на компьютере Ubuntu, и я немного не понимаю, в чем может быть разница.4. Можете ли вы отредактировать свой вопрос с
nm
выводом для этой функции в обоих.so
файлах? Я подозреваю, что это может быть из-за видимости по умолчанию.5. Выполнено. Я подумал то же самое, но подумал, что видимость по умолчанию общедоступна (хотя я здесь не в своей тарелке).