c++ - 使用 bjam 编译的来自 C++ 的未定义符号
问题描述
我有一个通过 Boost Python 与 C++ 交互的 Python 应用程序。应用程序的 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
}
}
它位于头文件 ch 中:
/dir/folder2/ch
#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 ;
解决方案
当 C++ 代码被编译时,名称会被破坏。C 代码不会被破坏。C++ 名称修改对公开函数造成了问题……实际上是在任何地方。
该问题的解决方案是将 C++ 调用包装在类似 C 的接口下,这样名称就不会被破坏。例如,要将您返回std::string VAR
到 C(最终返回到 Python):
extern "C"
{
const char* get_var(void){ return VAR.c_str();}
}
Boost.Python 知道这一切,并试图通过使用宏隐藏 extern "C" 位来使事情变得更容易,例如BOOST_PYTHON_MODULE
该extern "C"
技巧主要用于将 C++ 代码暴露给其他语言。(但是,C# 有 CLR 和 PInvoke)
推荐阅读
- point-cloud-library - 如何将 CGAL 点转换为 PCL 点云?
- javascript - 修复定位元素问题
- node.js - 使用 Getstream 获取所有频道
- java - Java问题通过创建学生管理程序
- sas - Proc Export 以在 SAS 中使用格式/布局更新 excel 表
- android - 使用 Android Studio 时通过 USB 连接时无法在手机上运行/调试应用程序(安装时会断开连接)
- sql-server - 如何从具有身份的 SQL Server 获取用户信息
- r - 从 for 循环中的列表访问文件
- metadata - 实时流媒体音频的实时元数据/字幕
- javascript - 如何将 svg 添加到无序列表?