如何创建从抽象 c++ 派生的类的 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 is my code:
// 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()
I want to make python class derived from c++ abstract class and then pass this object back to c++. How should I do that without crash?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这有点复杂,但并不困难。 阅读此页面< /a>,它应该为您提供所需的一切。
您需要像这样包装抽象类:
然后您必须按如下方式公开 Base:
It's a little complicated, but not difficult. Read this page, it should give you everything you need.
You need to wrap the abstract class like this:
Then you have to expose Base as follows:
您可能还想查看 Py++ 包。 它是一个用于解析 C++ 代码并为该代码生成 boost::python 包装器的实用程序。 我只尝试了一点,但它似乎可以处理自动创建基类包装器和类似的事情(根据文档,作者能够导出几个boost库并通过生成绑定来在Python中运行他们的测试套件py++)。
You might also want to check out the Py++ package. It's a utility used for parsing C++ code, and generating boost::python wrappers for that code. I've only tried it a little, but it seems to handle automatically creating base class wrappers and things like that (and according to the docs, the author was able to export several boost libraries and run their test suites in Python by generating bindings via Py++).