我有一个Python应用程序通过Boost Python与C ++连接。应用程序的C ++段是使用Bjam构建的(Bjam make文件可以在底部找到)。 C ++编译(并且似乎链接)很好。
Python执行后不久就会抱怨从C ++文件引用的未定义符号。此C ++文件包含一个C ++标头,其中声明了未定义的符号。如果我删除对有问题的变量的引用,代码继续执行正常。
如果我在库上运行nm
,它会列出带有U(未定义)的符号。
有人可以帮忙我收到这个未定义的符号运行时错误吗?我认为这可能是因为我的gcc路径中没有包含某些东西?
python代码调用C ++方法,该方法使用C_NAMESPACE
中定义的变量创建对象:
/dir/folder1/bridge.cpp
#include "c.h"
namespace CPP
{
void calledByPython()
{
MyClass x(C_NAMESPACE::VAR);
// continues
}
}
位于头文件c.h中:
/dir/folder2/c.h
#ifndef C_H
#define C_H
namespace C_NAMESPACE
{
extern const std::string VAR;
}
源文件的位置如下:
/dir/folder2/c.cpp
#include "c.h"
namespace
{
const std::string VAR = "something";
}
我正在使用bjam构建这个C ++:
import python ;
lib gbclientlib : : <name>gbclient <search>$(gbclient_dir)/lib <link>static ;
explicit gbclientlib ;
project gb
: requirements
<location>.
<cxxflags>"-std=c++11 -Wno-deprecated -I /dir/folder1/ -I /dir/folder2/"
;
python-extension _bridge : bridge.cpp ;
答案 0 :(得分:1)
编译C ++代码时,名称会被破坏。 C代码不会被破坏。 C ++名称修改会给实现任何地方的函数带来问题。
问题的解决方案是将C ++调用包装在类似C的接口下,这样名称就不会被破坏。例如,要将std::string VAR
返回到C(最终是Python):
extern "C"
{
const char* get_var(void){ return VAR.c_str();}
}
Boost.Python知道这一切并试图通过隐藏extern&#34; C&#34;像BOOST_PYTHON_MODULE
extern "C"
技巧主要用于将C ++代码暴露给其他语言。 (但是,C#有CLR和PInvoke)