是否可以在Python模块中定义的类的C ++程序中创建实例?

时间:2015-06-21 18:06:30

标签: c++ boost-python

我想要做的是在C ++程序中创建一个虚拟类(ClassTest),然后在Python脚本中导入它,在该脚本中创建派生类,然后用C ++导回该派生类。

这是我到目前为止提出的代码:

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

using namespace boost::python;
using namespace std;

class ClassTest {
public:
    ClassTest () {}

    virtual int someFunction () = 0;
};

BOOST_PYTHON_MODULE(ClassTest) {
    class_< ClassTest, boost::noncopyable >("ClassTest", no_init)
        .def("someFunction", &ClassTest::someFunction)
    ;
}

int main() {
    try {

        Py_Initialize();

        initClassTest();

        ClassTest* testObject = **???**

        cout << "Function result = " << testObject.someFunction() << endl;

        Py_Finalize();

    } catch (error_already_set& e) {

        PyErr_PrintEx(0);
        return 1;

    }

    return 0;
}

还有Python脚本:

import ClassTest

class classTestChild(ClassTest.ClassTest):
    def someFunction ():
        return 4;

1 个答案:

答案 0 :(得分:0)

以下是完成此示例的完整示例。您需要一个包装类,以便可以在Python中覆盖虚函数。

ClassTest.h:

class ClassTestWrap : public ClassTest, public python::wrapper<ClassTest>
{
public:
    virtual int someFunction() override
    {
        if (python::override f = this->get_override("someFunction"))
            return f();
        return ClassTestWrap::someFunction();
    }
};

BOOST_PYTHON_MODULE(ClassTest)
{
    python::class_< ClassTestWrap, boost::noncopyable >("ClassTest")
    .def("someFunction", python::pure_virtual(&ClassTestWrap::someFunction));
}

ClassTest.cpp(必须内置到.so / .dll中):

try
{
    Py_Initialize();
    python::object main = python::import("__main__");
    python::object global(main.attr("__dict__"));
    python::object ignored = python::exec("import ClassTest\n"
                                          "class classTestChild(ClassTest.ClassTest):\n"
                                          "    def someFunction(self):\n"
                                          "        return 4\n"
                                          "\n"
                                          "child = classTestChild()", global);
    ClassTest *obj = python::extract<ClassTest*>(global["child"]);
    int value = obj->someFunction();
    printf("value = %d\n", value);
    Py_Finalize();
}
catch (python::error_already_set&)
{
    PyErr_Print();
    PyErr_Clear();
}

main.cpp(可执行文件):

value = 4

输出:

{{1}}

如果ClassTest.so/ClassTest.dll和.exe位于同一文件夹中并且从同一文件夹(./test.exe)调用.exe,则此示例将起作用