Неопределенный символ из C++, скомпилированный с использованием bjam
У меня есть приложение Python, взаимодействующее с C++ через Boost Python. Сегмент C++ приложения построен с использованием Bjam (файл make для Bjam можно найти внизу вопроса). 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/ ч
#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";
}
и я строю этот C++, используя bjam:
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 ответ
Когда код C++ компилируется, имена искажаются. С код не искажается. Смена имен в C++ создает проблему для раскрытия функций... где угодно.
Решение проблемы - обернуть вызовы C++ в C-подобные интерфейсы, чтобы имя не искажалось. Например, чтобы вернуть std::string VAR
в C (и в конечном итоге Python):
extern "C"
{
const char* get_var(void){ return VAR.c_str();}
}
Boost.Python знает все это и пытается упростить вам задачу, скрывая внешние биты "C" с помощью таких макросов, как BOOST_PYTHON_MODULE
extern "C"
Трюк используется в основном для представления кода C++ для других языков. (C#, однако, имеет CLR и PInvoke)