Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 无法使用boost.python导入模块_C++_Boost_Boost Python - Fatal编程技术网

C++ 无法使用boost.python导入模块

C++ 无法使用boost.python导入模块,c++,boost,boost-python,C++,Boost,Boost Python,我正在尝试使用boost.python构建一个简单的程序 我有以下代码: //greet.cpp #include <iostream> #include <boost/python.hpp> void greet() { std::cout << "hello world!" << std::endl; } BOOST_PYTHON_MODULE(greet) { using namespace boost::python;

我正在尝试使用boost.python构建一个简单的程序
我有以下代码:

//greet.cpp
#include <iostream>
#include <boost/python.hpp>

void greet()
{
    std::cout << "hello world!" << std::endl;
}

BOOST_PYTHON_MODULE(greet)
{
    using namespace boost::python;
    def("greet", greet);
}
运行
makegreet.so
时只会出现一些警告(在一些boost文件中重新定义)

当我尝试用python导入模块时,我得到以下结果:

Python 2.7.3 (default, Apr 10 2013, 05:46:21) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import greet
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: ./greet.so: undefined symbol: _ZNK5boost6python7objects21py_function_impl_base9max_arityEv

boostpython需要boostpython
so
文件。当您以多种方式运行python时,可以将其添加到路径中。我正在使用

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH:../ThirdParty/boost_1_52_0/lib/linux64/

boostpython需要boostpython
so
文件。当您以多种方式运行python时,可以将其添加到路径中。我正在使用

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH:../ThirdParty/boost_1_52_0/lib/linux64/
请注意,当您使用gcc链接二进制文件时。将二进制文件传递给链接器的顺序应确保第一个单元(例如,您的对象文件)应使用以下单元(其他对象文件或库)解析。在您的示例中,您正在链接
问候语。因此
错误:

%.so: %.o
    gcc ${CLinkFlags} -o $@ $^
这将生成如下编译行:

gcc -shared -Wl,-soname,greet.so -L/usr/lib -lboost_python -L/usr/lib/python2.7 -lpython2.7 -o greet.so greet.o
请注意,单元
greet.o
,它依赖于
libboost_python.so
libpython2.7中定义的符号。因此
排在最后,因此,当gcc的链接器到达它时,它无法再解析未定义的符号。不幸的是,这不是一个错误,因为链接器无法知道您是否需要它(例如,在Python中,libpythonX.Y将在您导入代码之前加载,因此可能会跳过它-您可以从命令行完全转储该库)。因此,默认设置是忽略所有未定义的符号

您可以通过设置两个标志来强制检测未定义的符号,从而更改该行为:

CLinkFlags += -Wl,--unresolved-symbols=report-all
将所有未解析的符号报告为错误,并且:

CLinkFlags += -Wl,--unresolved-symbols=report-all -Wl,--warn-unresolved-symbols
将报告所有未解析的符号,但仍将链接二进制文件。你有其他的选择被警告:这不是你通常想要的。例如,
libpythonX.Y
之类的东西从未显式链接,但它们在运行时仍然可用。实际上,您仍然会得到一堆不值得探究的伪未定义引用。最好是修复Makefile,并确保目标代码在库之前出现

要修复您的示例,只需将
$^
移动到链接的开始处,如下所示:

gcc $^ ${CLinkFlags} -o $@
编译并运行
ldd
后,您应该会看到现在
libboost\u python
(以及
python
,因为您正在显式链接它)将链接到
greet。因此
和加载应该按照您的预期工作。我自己在当地测试过

根据经验,如果您对gcc有未定义的引用,并且您确信它们应该出现在任何链接代码中,请仔细检查顺序

这里是一个完全工作/最小版本的Makefile,它将为您的特定案例执行任务(注意,我们还将运行时路径设置为您的私有boost库,因此您不需要设置
LD_library_path
,如其他答案所示-请参阅下面的详细信息):

通过打开库本身,运行时链接器在尝试
LD\u library\u路径之前会自动首先查看该库。如果您决定不这样做,则必须按照其他答案设置环境变量
LD\u LIBRARY\u PATH

请注意,当您将二进制文件链接到gcc时。将二进制文件传递给链接器的顺序应确保第一个单元(例如,您的对象文件)应使用以下单元(其他对象文件或库)解析。在您的示例中,您正在链接
问候语。因此
错误:

%.so: %.o
    gcc ${CLinkFlags} -o $@ $^
这将生成如下编译行:

gcc -shared -Wl,-soname,greet.so -L/usr/lib -lboost_python -L/usr/lib/python2.7 -lpython2.7 -o greet.so greet.o
请注意,单元
greet.o
,它依赖于
libboost_python.so
libpython2.7中定义的符号。因此
排在最后,因此,当gcc的链接器到达它时,它无法再解析未定义的符号。不幸的是,这不是一个错误,因为链接器无法知道您是否需要它(例如,在Python中,libpythonX.Y将在您导入代码之前加载,因此可能会跳过它-您可以从命令行完全转储该库)。因此,默认设置是忽略所有未定义的符号

您可以通过设置两个标志来强制检测未定义的符号,从而更改该行为:

CLinkFlags += -Wl,--unresolved-symbols=report-all
将所有未解析的符号报告为错误,并且:

CLinkFlags += -Wl,--unresolved-symbols=report-all -Wl,--warn-unresolved-symbols
将报告所有未解析的符号,但仍将链接二进制文件。你有其他的选择被警告:这不是你通常想要的。例如,
libpythonX.Y
之类的东西从未显式链接,但它们在运行时仍然可用。实际上,您仍然会得到一堆不值得探究的伪未定义引用。最好是修复Makefile,并确保目标代码在库之前出现

要修复您的示例,只需将
$^
移动到链接的开始处,如下所示:

gcc $^ ${CLinkFlags} -o $@
编译并运行
ldd
后,您应该会看到现在
libboost\u python
(以及
python
,因为您正在显式链接它)将链接到
greet。因此
和加载应该按照您的预期工作。我自己在当地测试过

根据经验,如果您对gcc有未定义的引用,并且您确信它们应该出现在任何链接代码中,请仔细检查顺序

这里是一个完全工作/最小版本的Makefile,它将为您的特定案例执行任务(注意,我们还将运行时路径设置为您的私有boost库,因此您不需要设置
LD_library_path
,如其他答案所示-请参阅下面的详细信息):

通过打开库本身,运行时链接器在尝试
LD\u library\u路径之前会自动首先查看该库。如果你