Неопределенный символ из C ++, скомпилированный с использованием bjam - PullRequest
0 голосов
/ 03 мая 2018

У меня есть приложение Python, взаимодействующее с C ++ через Boost Python. Сегмент C ++ приложения построен с использованием Bjam (файл make Bjam можно найти внизу вопроса). C ++ компилируется (и, кажется, связывается) нормально.

Вскоре после запуска Python жалуется на неопределенный символ, на который ссылается файл C ++. Этот файл C ++ содержит заголовок C ++, в котором объявлен неопределенный символ. Если я удалю ссылку на проблемную переменную, код продолжит выполняться нормально.

Если я запускаю nm в библиотеке, в нем будет указан символ с символом U (не определено).

Может кто-нибудь помочь, почему я получаю эту неопределенную ошибку времени выполнения символа? Я думаю, что это, вероятно, потому что я не включил что-то в свой путь GCC?

Код Python вызывает метод C ++, который создает объект, используя переменную, определенную в C_NAMESPACE:

/ реж / folder1 / bridge.cpp

#include "c.h"

namespace CPP
{
    void calledByPython()
    {
        MyClass x(C_NAMESPACE::VAR);
        // continues
    }
}

, который находится в заголовочном файле c.h:

/ реж / folder2 / c.h

#ifndef C_H
#define C_H

namespace C_NAMESPACE
{
    extern const std::string VAR;
}

где исходный файл выглядит так:

/ реж / 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 Ответ

0 голосов
/ 03 мая 2018

Когда код 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)

...