将Cython中的有界方法作为argumen传递

2024-04-26 13:56:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图把一些C++代码封装到Cython,我试图把一个方法从一个类传递给一个函数,遇到了一些麻烦。在

我不知道它是否使它更清楚,但是类A代表一个统计模型(因此myAMethod不仅使用传递的参数,而且使用许多实例变量),而B有不同的方法来最小化传递的函数。在

在C++中,我有这样的风格: class A { public: double myAMethod(double*) }; class B { public: double myBMethod(A&, double (A::*f) (double*) }

所以我要做的是在Cython代码中同时使用A和B的实例。包装类没有问题,但是当我尝试使用myBMethod时,我不知道如何传递A::*myAMethod类型的指针

如果我这样做: myBMethod(ptrToAObj[0], &ptrToAObj.myAMethod), 然后Cython将这段代码编译成[...] &ptrToAObj->myAMethod [...],我从g++中得到了预期的消息:

"ISO C++ forbids taking the address of a bound member function to form a pointer to member function."

但是如果我试图直接指向类方法,并执行myBMethod(ptrToAObj[0], A.myAMethod),那么Cython就不会编译并这样说

myAMethod is not a static member from A.

这几乎就是我所能提升的。我可以在C++级别工作,避免这些异常现象,但是如果我能够在Python(通过Cython)交互地使用A和B的实例,它将帮助我加快我的开发速度。 任何帮助都将非常感谢,如果这个问题已经得到了回答和/或在参考文献中可以找到-我搜索,所以,赛顿参考和史密斯的“赛顿”的书,我没有找到这个主题。 提前谢谢!在


Tags: to实例方法函数代码function代表public
1条回答
网友
1楼 · 发布于 2024-04-26 13:56:53

我有一个部分(如果可怕的)解决方案。我准备相信有更好的方法,但我不知道。在

在cpp中_钻头水电站公司名称:

class A { 
  public:
    double myAMethod(double*) { return 0.0; }
}; 

typedef double (A::*A_f_ptr)(double *);

class B {
 public:
   double myBMethod(A& a, A_f_ptr f) { 
     double x = 0.1;
     return (a.*f)(&x);
   }
};

A_f_ptr getAMethod() {
  return &A::myAMethod;
}

我给了这些函数非常基本的实现,这样我就可以检查是否有明显的崩溃。我还创建了一个函数指针,它返回一个指向myAMethod的指针。您需要对每个要包装的方法执行此操作。在

在py中_位.pyx在

^{pr2}$

我不知道如何在Cython中键入成员函数指针,所以我创建了一个同名的空cppclass。这是因为cython似乎只是将它用于类型检查,而没有其他用途,而且它包含cpp_钻头水电站(在定义它的地方)你可以使用它没有问题。在

我所做的就是让成员函数指针指向c++(在getAMethod中,我调用它)。我不认为这是完全令人满意的,但它看起来是可行的,而且对于你想访问的每个成员函数来说,它只是一个简短的额外的c++函数。你可以把它放在哪里,这样可以更干净地封装它。在

另一种未经测试的方法:(编辑:进一步思考表明这可能非常棘手!请自行承担风险!)在

就个人而言,我很想更改c++接口,以便myBMethod被定义为

double myBMethod(std::function<double (double*)>)

(因为您可能总是用它传递的A实例来调用它)。然后使用c++中的lambda函数(11!)将实例和函数包装在一起

b.myBMethod([&](double* d){ return a.myAMethod(d) };

然后可能需要一点非常复杂的Cython包装,我还没有考虑过,但是应该可以将一个简单的double (double*)函数指针转换为c++函数对象,从而更直接地使用它。在

你的实际设计也有可能比我没有考虑过的更复杂,而且这种方法无论如何都不够灵活。在

相关问题 更多 >