链接python扩展模块

2024-09-30 04:33:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个扩展模块,富有想象力地命名为foobar^{< CD2>}由一个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", &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", &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._foofoo._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输出

$ 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

Tags: fromimportaddreturnfooincludeosextension

热门问题