0

私は現在、複雑なプログラムの一部をダイナミックライブラリに入れようとしています。この部分は、ブースト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

次に、アプリケーションのメイン関数で、Pythonを埋め込むクラスのインスタンスを作成しますが、関数がダイナミックライブラリlibFoo.dllで定義されていても、World :: foo()への未定義の参照が提供されます。メインアプリケーション。

main.cpp:

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

using namespace std;

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

    World world;

    world.foo();
}

コンソール:

undefined reference to `World::foo()'

MinGWでCode::Blocksを使用しています。

この問題は私を何日か目覚めさせてくれました、そして私はそれを解決する方法を見つけることができないようです。あなたが私を助けてくれることを願っています。

前もって感謝します。

アップデート:

私は今、通常のPythonCAPIを使用してこのタスクを実行しようとしました。このエラーが確実に関連しているPython_Module(BOOST_PYTHON_MODULE())を定義する手順は、次のような関数を定義することによって行われます。

PyMODINIT_FUNC initHello(void){
...
}

今これの前に書いています

#define PyMODINIT_FUNC void

エラーを解決します。boost.pythonライブラリがBOOST_PYTHON_MODULE関数をどのように定義するか誰かがいますか?たぶん、この種の解決策もありますか?ソースファイルにPyMODINIT_FUNCのものが見つかりませんでした。

4

1 に答える 1

0

自分で解決策を見つけました。

それは私がすでに推測したようなものです。必要なのは、このようにBOOST_PYTHON_MODULE_INIT(name)を定義することです。

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

実際、これはいくつかの#ifdefが前に付いているヘッダーファイルの1つで見つかりましたが、正しく機能していないようです。少なくとも私にとってはそうではありません。

于 2012-12-03T10:21:09.340 に答える