我正在使用cppyy。我想将一个函数传递给我的C ++。 C ++期望签名std::function<double(std::vector<double>)>
的功能。我不知道该怎么做。这是错误的最小示例:
import cppyy
# To be passed to C
def callback(x):
return 10.
cppyy.cppdef("double callback_vector(const std::function<double(std::vector<double>)>& callback, std::vector<double> x) { return callback(x); }")
cppyy.cppdef("double callback(const std::function<double(double)>& callback, std::vector<double> x) { return callback(x[0]); }")
cppyy.gbl.callback(callback, [1]) # works
cppyy.gbl.callback_vector(callback, [1]) # fails
但我发现
Traceback (most recent call last):
File "test.py", line 11, in <module>
cppyy.gbl.callback_vector(callback, [1])
TypeError: double ::callback_vector(function<double(std::vector<double> >& callback, vector<double> x) =>
TypeError: could not convert argument 1
换句话说,使用std::function<double(std::vector<double>)>
失败,但是使用更简单的std::function<double(double)>
签名则可以工作。
正如所评论的,问题出在后端的深处(一个解析错误),这使std::function
名称变成了无法识别的名称。这样做是为了解决我尝试过的一系列变通方法。
我能想到的最接近的解决方案是:
cppyy.cppdef("""
struct VecDArg : public std::vector<double> {
VecDArg(const std::vector<double>& v) : std::vector<double>(v) {}
};
double wrap_callback_vector(const std::function<double(VecDArg)>& wrap, const std::vector<double>& x) {
return callback_vector(wrap, x);
}
""")
cppyy.gbl.callback_vector = cppyy.gbl.wrap_callback_vector
cppyy.gbl.callback_vector(callback, [1])
上面的方法起作用的原因是,它从后端隐藏了类型名称,从而避免了解析问题。通过从std::vector
派生,Python类几乎是最明智的。
我将在固定到上游时报告。