c++ - 如何创建从抽象c++类派生的类的python对象实例?

标签 c++ extract boost-python

这是我的代码:

// c++ (main.cpp)
#include <vector>
#include <iostream>
#include <boost/python.hpp>
#include <boost/python/enum.hpp>
#include <boost/python/def.hpp>
#include <boost/python/module.hpp>

using namespace std;
using namespace boost;
using namespace boost::python;

class Base
{
public:
    Base(void) {}
virtual void f1(void) = 0;
virtual void f2(void) = 0;
};

class Stack
{
public:
Stack(void) {}
void push(Base *e)
{
    stack.push_back(e);
}
void pushPython(boost::python::object &o)
{
    Base &e = extract<Base &>(o) BOOST_EXTRACT_WORKAROUND;
    push(&e);
}
void test(void)
{
    for(std::vector<Base *>::iterator i = stack.begin(); i != stack.end(); i++)
    {
        (*i)->f1();
        (*i)->f2();
    }
}
private:
std::vector<Base *> stack;
};


class DerivedCPP : public Base
{
public:
DerivedCPP(void) {}
virtual void f1(void)
{
    std::cout << "DerivedCPP f1()" << std::endl;
}
virtual void f2(void)
{
    std::cout << "DerivedCPP f2()" << std::endl;
}
};

BOOST_PYTHON_MODULE(mytest)
{
boost::python::class_<Base,boost::noncopyable>("Base",boost::python::no_init)
    .def( "f1", &Base::f1)
    .def( "f2", &Base::f2)
    ;

boost::python::class_<DerivedCPP,bases<Base>>("DerivedCPP")
    .def( "f1", &DerivedCPP::f1)
    .def( "f2", &DerivedCPP::f2)
    ;

boost::python::class_<Stack>("Stack", boost::python::no_init)
    .def( "push", &Stack::pushPython)
    .def( "test", &Stack::test)
    ;
}

int main(int argc, char** argv)
{
PyImport_AppendInittab("mytest", &initmytest);
Py_Initialize();
boost::python::object main_module(( handle<>( borrowed( PyImport_AddModule( "__main__" )))));
boost::python::object main_namespace = main_module.attr("__dict__");
boost::python::object mytest( (handle<>(PyImport_ImportModule("mytest"))) );
main_namespace["mytest"] = mytest;
Stack *STACK = new Stack();
main_namespace["Stack"] = ptr(STACK);
Base *e = new DerivedCPP();
STACK->push(e);
STACK->test();
boost::python::object main = import("__main__");
boost::python::object global(main.attr("__dict__"));
boost::python::object result = exec_file("test.py", global, global);
Py_Finalize();
return 0;
}


# python (test.py)
print 'test.py'
print

class DerivedPython(mytest.Base):
def __init__(self):
    print "DerivedPython __init__()"
def f1(self):
    print "DerivedPython f1()"
def f2(self):
    print "DerivedPython f2()"

print 'DerivedPython()'
p = DerivedPython()
p.f1()
p.f2()

print 'mytest.DerivedCPP()'
c = mytest.DerivedCPP()
c.f1()
c.f2()

print 'Stack.push(c)'
Stack.push(c)
print 'OK'

print "Stack.test()"
Stack.test()

print 'Stack.push(p)'
Stack.push(p) # crash!
print 'OK'

print "Stack.test()"
Stack.test()

我想让Python类从C++抽象类派生,然后将此对象传递回C++。我应该如何做到这一点而不崩溃?

最佳答案

有点复杂,但并不难。阅读 this page ,它应该为您提供所需的一切。

您需要像这样包装抽象类:

struct BaseWrap : Base, wrapper<Base>
{
    void f1()
    {
        this->get_override("f1")();
    }

    void f2()
    {
        this->get_override("f2")();
    }

};

然后你必须按如下方式公开 Base:

class_<BaseWrap, boost::noncopyable>("Base")
    .def("f1", pure_virtual(&Base::f1))
    .def("f2", pure_virtual(&Base::f2))
    ;

关于c++ - 如何创建从抽象c++类派生的类的python对象实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/594787/

相关文章:

c++ - 为 STL sort() 重载 "< "

r - 如何从 R 中的栅格中提取值

c# - 在 C# 中使用正则表达式分组的子字符串

bash - 使用bash脚本提取某些类型名称和对应的数字

c++ - 使用 boost.python 时 c++ 流有什么问题?

c++ - boost::python 在结构中访问结构

c++ - 为什么 C++ 变量声明语法不一致?

c++ - 创建没有重复项的新排序 vector

c++ - Win32中的窗口边框宽度和高度 - 我如何获得它?

python - 合成子模块 : from A import B (ok) vs. 导入 A.B(错误)?