如何执行
c++ -> Python -> c++
^ |
| |
-----------------
带有代码的示例:
想象一下我有一个为python包装的C ++类(例如,使用boost.python)
// foo.cpp
#include <boost/python.hpp>
struct Cat {
Cat (int fur=4): _fur{i} { }
int get_fur() const { return _fur; }
private:
int _fur;
};
BOOST_PYTHON_MODULE(foo) {
using namespace boost::python;
class_<Cat>("Cat", init<int>())
.def("get_fur", &A::get_fur, "Density of cat's fur");
}
现在我正在用C ++托管python。 python脚本创建Cat =>在下面创建一个c ++ Cat实例。如何从托管c ++(从C ++到C ++)获取指向Cat的c ++实例的指针?
#include <Python.h>
int
main(int argc, char *argv[])
{
Py_SetProgramName(argv[0]); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("from cat import Cat \n"
"cat = Cat(10) \n");
// WHAT to do here to get pointer to C++ instance of Cat
... ??? ...
std::cout << "Cat's fur: " << cat->get_fur() << std::endl
Py_Finalize();
return 0;
}
实际应用真正的问题是:我们有一个c ++框架,该框架具有相当复杂的初始化和配置阶段,而性能并不重要;然后是处理阶段,性能就是一切。该框架有一个python包装。在python中定义内容非常方便,但是从python运行仍然比纯c ++代码慢。出于多种原因,在python中进行此配置/初始化阶段,获取指向C ++对象下方的指针,然后在“纯c ++模式”下运行的诱因是很诱人的。如果我们可以从头开始编写所有内容,那将很容易,但是我们已经定义了很多(已有30年的历史了)c ++框架。
如果包装器是开源的,请使用C ++中包装器的python对象结构。将PyObject *强制转换为该结构(该结构应将PyObject作为其第一个成员iirc,并只需访问指向C ++实例的指针即可。通过在Python中保留包装实例,确保在使用实例时不删除该实例。发布它时,它可能会删除您现在仍然持有指向它的包装的C ++实例。并且请记住,这种方法是冒险且脆弱的,因为它取决于包装程序的实现细节,在将来的版本中可能会发生变化。