在动态库undefined引用中提升python包装器

时间:2012-11-18 21:38:09

标签: c++ boost-python undefined-reference dynamic-library

我目前正在尝试将复杂程序的一部分放入动态库中。这部分由一些类组成,这些类也用boost python包装成一个模块,再次嵌入。这是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

在应用程序的main函数中,我创建了一个嵌入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 with MinGW。

这个问题让我在某些日子里保持清醒,而我似乎无法找到解决问题的方法。希望您能够帮助我。

提前致谢。

更新:

我现在尝试使用普通的Python C API来解决这个问题。定义这个错误肯定连接的Python_Module(BOOST_PYTHON_MODULE())的步骤是通过定义一个函数来完成的:

PyMODINIT_FUNC initHello(void){
...
}

现在写下这个

#define PyMODINIT_FUNC void

解决了这个错误。现在有人如何使用boost.python库定义BOOST_PYTHON_MODULE函数?也许还有这种解决方案?我在源文件中找不到任何PyMODINIT_FUNC内容。

1 个答案:

答案 0 :(得分: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,但似乎它们无法正常工作。至少不适合我。