本文介绍了Cython和c ++类构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人建议使用Cython操纵c ++对象的方法,当
时,一个类的c ++实例将如下所述提供另一个包装的
类的构造函数?



请参考PySession类的注释,其中
使用python PyConfigParams对象作为参数,然后需要
提取值,以便构造一个c ++ ConfigParams
对象。然后使用ConfigParams对象来提供Session的构造函数



这将是理想的有一个程序,这将允许我注入
ConfigParams c ++对象包装的PyConfigParams对象
直接Session的构造函数,而不必先拆卸
,然后构建一个新的c ++对象来构造函数。
这当然是。然而,实施这个解决方案是一种麻烦,粗暴的方式,更不用说不可靠。



我知道PyCapsule,但它可能需要触摸c ++标题,这是我不能做的。


$ b $与此相关,但一个不同的问题是:如果我需要一个封装的
类(这里说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;
#includeconfigparams.h
class Session
{
int sessionX;
public:
Session(ConfigParams parameters){this-> sessionX = parameters.getPar1(); }
void doSomething();
};

void Session :: doSomething()
{
cout< 会话参数设置为:< endl;
cout<< X =<< this-> sessionX< endl;
}



上述类的Cython pyx和pxd文件:



PyConfigParams



 #configparams.pxd 
cdef extern fromconfigparams.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 b $ b return self.thisptr.getPar1()



PySession类



 #session.pxd 
来自configparams cimport *
cdef extern fromsession.h:
cdef cppclass Session:
Session(ConfigParams parameters)
void doSomething()

#session.pyx
cdef class PySession:
cdef Session *注意,这里我必须从pars(python PyConfigParams对象)
#中提取值
#,以构建一个c ++ ConfigParams对象
#,它提供了Session的c ++构造函数。
cdef ConfigParams * cpppargsptr = new ConfigParams(< int> pars.getPar1())
self.thisptr = new Session(cpppargsptr [0])
def doSomething $ b self.thisptr.doSomething()


解决方案


在configparams.pxd模块中转发声明PyConfigParams(因此可以从session.pyx模块调用)

 #configparams.pxd 
cdef extern fromconfigparams.h:
cppclass ConfigParams:
ConfigParams(int par1)
int getPar1 ()

cdef class PyConfigParams:
cdef ConfigParams * thisptr

在session.pyx模块中导入PyConfigParams,并为constuctor转换参数,这将允许访问PyConfigParams指向c ++对象的指针,这需要被解引用。

 #session.pyx 
来自configparams cimport PyConfigParams
来自cython.operator cimport dereference as deref

cdef class PySession:
cdef Session * thisptr
def __cinit __(self,PyConfigParams pars):
self.thisptr = new Session(deref(pars.thisptr))
def doSomething(self):
self.thisptr.doSomething()


Can someone suggest a way to manipulate c++ objects with Cython, whenthe c++ instance of one class is expected to feed the constructor of another wrappedclass as described below?

Please look at the note on the pyx file for the class PySession, whichtakes a python PyConfigParams object as argument and then needs toextract values from it in order to construct a c++ ConfigParamsobject. the ConfigParams object is then used to feed the constructorof Session.

It would be ideal to have a procedure which would allow me to "inject"the ConfigParams c++ object wrapped by the PyConfigParams objectdirectly into the constructor of Session, without having to dismantleit first and then building a new c++ object to feed the constructor.This works, of course. However, it is a cumbersome, sort of brutal way to implement this solution, not to mention unreliable.

I am aware of PyCapsule, however it may require to touch the c++ headers, which is something I can not do.

Related to this, but a different question is: what if I need a wrappedclass (let's say here PySession) to simulate the behavior of the C++api by returning a ConfigParams instance? would I need to do thereverse and dismantle the c++ object to build a Python PyConfigParamswhich would then be returned to the Python user in the Python world?Any suggestions are very welcome!Thank you!

Let's suppose I have two c++ classes named ConfigParams and Session.An instance of ConfigParams is used to feed the constructor of theSession class:

C++ classes

ConfigParams class

// ConfigParams.h
#include <iostream>
using namespace std;
class ConfigParams
{
  int parameter1;
 public:
  ConfigParams(int par1) { this->parameter1 = par1;}
  int getPar1() { return this->parameter1; }
};

Session class

// 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 and pxd files for the above classes:

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 class

# 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()
解决方案

Solution:

Forward declare PyConfigParams in the configparams.pxd module (so it can be invoked from the session.pyx module)

# configparams.pxd
cdef extern from "configparams.h":
    cppclass ConfigParams:
        ConfigParams(int par1)
        int getPar1()

cdef class PyConfigParams:
    cdef ConfigParams* thisptr

Import PyConfigParams in the session.pyx module, and cast the argument for the constuctor, this will grant access to the PyConfigParams pointer to the c++ object, which will need to be dereferenced.

# session.pyx
from configparams cimport PyConfigParams
from cython.operator cimport dereference as deref

cdef class PySession:
    cdef Session* thisptr
    def __cinit__(self, PyConfigParams pars):
        self.thisptr = new Session(deref(pars.thisptr))
    def doSomething(self):
        self.thisptr.doSomething()

这篇关于Cython和c ++类构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 14:25