使用bjam编译的C ++中未定义的符号

时间:2018-05-03 13:24:47

标签: c++ linker boost-python bjam b2

我有一个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 ;

1 个答案:

答案 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)