有人可以建议一种使用 Cython 操作 c++ 对象的方法,当一个类的 c++ 实例预计将提供另一个包装类的构造函数时,如下所述?
请查看 PySession 类的 pyx 文件上的注释,该类将 python PyConfigParams 对象作为参数,然后需要从中提取值以构造 c++ ConfigParams 对象。然后使用 ConfigParams 对象来提供 Session 的构造函数。
最好有一个过程,它允许我将 PyConfigParams 对象包装的 ConfigParams c++ 对象直接“注入”到 Session 的构造函数中,而不必先拆除它,然后再构建一个新的 c++ 对象来提供构造函数。这当然有效。然而,实现这个解决方案是一种繁琐、残酷的方式,更不用说不可靠了。
我知道 PyCapsule,但是它可能需要触摸 c++ 标头,这是我无法做到的。
与此相关,但另一个问题是:如果我需要一个包装类(我们在这里说 PySession)通过返回一个 ConfigParams 实例来模拟 C++ api 的行为怎么办?我是否需要反向操作并拆除 c++ 对象来构建 Python PyConfigParams,然后将其返回给 Python 世界中的 Python 用户?非常欢迎任何建议!谢谢!
假设我有两个名为 ConfigParams 和 Session 的 C++ 类。ConfigParams 的一个实例用于提供 Session 类的构造函数:
C++ 类
ConfigParams 类
// ConfigParams.h
#include <iostream>
using namespace std;
class ConfigParams
{
int parameter1;
public:
ConfigParams(int par1) { this->parameter1 = par1;}
int getPar1() { return this->parameter1; }
};
会话类
// Session.h
#include <iostream>
using namespace std;
#include "configparams.h"
class Session
{
int sessionX;
public:
Session(ConfigParams parameters) { this->sessionX = parameters.getPar1(); }
void doSomething();
};
void Session::doSomething()
{
cout << "Session parameters set as: " << endl;
cout << "X = " << this->sessionX << endl;
}
上述类的 Cython pyx 和 pxd 文件:
PyConfigParams
# configparams.pxd
cdef extern from "configparams.h":
cppclass ConfigParams:
ConfigParams(int par1)
int getPar1()
# configparams.pyx
cdef class PyConfigParams:
cdef ConfigParams* thisptr
def __cinit__(self, i):
self.thisptr = new ConfigParams(<int> i)
def getPar1(self):
return self.thisptr.getPar1()
PySession 类
# session.pxd
from configparams cimport *
cdef extern from "session.h":
cdef cppclass Session:
Session(ConfigParams parameters)
void doSomething()
# session.pyx
cdef class PySession:
cdef Session* thisptr
def __cinit__(self, pars):
# Note that here I have to extract the values
# from the pars (python PyConfigParams object)
# in order to build a c++ ConfigParams object
# which feeds the c ++ constructor of Session.
cdef ConfigParams* cpppargsptr = new ConfigParams(<int> pars.getPar1())
self.thisptr = new Session(cpppargsptr[0])
def doSomething(self):
self.thisptr.doSomething()