увеличить оболочку Python в динамической библиотеке неопределенной ссылки

В настоящее время я пытаюсь поместить часть сложной программы в динамическую библиотеку. Эта часть состоит из некоторых классов, которые также обёрнуты с помощью python boost в модуль для повторного внедрения. Вот упрощенная версия источника DLL.

hello.cpp:

#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/python.hpp>
#include <Foo.h>

using namespace boost::python;

typedef boost::shared_ptr<Hello> hello_ptr;

BOOST_PYTHON_MODULE(Hello)
{
class_<Hello, hello_ptr>("Hello")
.def("say_hello", &Hello::say_hello)
;
};void Hello::say_hello(){
cout << "Hello World!" << endl;
}

void World::foo(){
Py_Initialize();

try {
PyRun_SimpleString(
"hello = None\n""\n""def setup(hello_from_cxx):\n""    print 'setup called with', hello_from_cxx\n""    global hello\n""    hello = a_foo_from_cxx\n""\n""def run():\n""    hello.say_hello()\n""\n""print 'main module loaded'\n");
//initialize eviroment
initHello();

hello_ptr hello = boost::make_shared<Hello>();

object main = object(handle<>(borrowed(
PyImport_AddModule("__main__")
)));

// pass the reference to hello into python:
object setup_func = main.attr("setup");
setup_func(hello);

// now run the python 'main' function
object run_func = main.attr("run");
run_func();
}
catch (error_already_set) {
PyErr_Print();
}
}

hello.h

#ifndef HELLO_H_INCLUDED
#define HELLO_H_INCLUDED

#include <iostream>
#include <boost/python.hpp>

using namespace std;

class Hello{
public:
void say_hello();
};

class World{
public:
void foo();
};

#endif // HELLO_H_INCLUDED

Затем в основной функции приложения я создаю экземпляр класса, который встраивает python, но дает неопределенную ссылку на World :: foo (), даже если эта функция определена в динамической библиотеке libFoo.dll, которая также связана с основное приложение.

main.cpp:

#include <iostream>
#include <Hello.h>

using namespace std;

int main(){
cout << "Test" << endl;

World world;

world.foo();
}

Приставка:

undefined reference to `World::foo()'

Я использую Code :: Blocks с MinGW.

Эта проблема не давала мне уснуть несколько дней, и я не могу найти способ ее решить. Надеюсь, ты сможешь мне помочь.

Заранее спасибо.

ОБНОВИТЬ:

Теперь я попытался решить эту задачу, используя обычный Python C API. Там шаг определения Python_Module (BOOST_PYTHON_MODULE ()), с которым эта ошибка определенно связана, выполняется путем определения функции, подобной:

PyMODINIT_FUNC initHello(void){
...
}

Сейчас пишу перед этим

#define PyMODINIT_FUNC void

решает ошибку. Кто-нибудь сейчас знает, как библиотека boost.python определяет функцию BOOST_PYTHON_MODULE? Может быть, есть и такое решение? Я не смог найти ничего из PyMODINIT_FUNC в исходных файлах.

0

Решение

Нашел решение сам.

Это как я уже догадался. Для этого нужно определить BOOST_PYTHON_MODULE_INIT (имя) следующим образом.

#   define BOOST_PYTHON_MODULE_INIT(name)                               \
void BOOST_PP_CAT(init_module_,name)();                               \
extern "C" __attribute__ ((__visibility__("default"))) _BOOST_PYTHON_MODULE_INIT(name)

На самом деле я обнаружил это в одном из заголовочных файлов с некоторым #ifdef infront, но кажется, что они работают неправильно. По крайней мере не для меня.

0

Другие решения

Других решений пока нет …