通过Python将C++对象传递给C++代码?
我写了一些物理模拟的代码,使用的是C++,但是解析输入的文本文件成了一个瓶颈。作为输入参数之一,用户需要指定一个数学函数,这个函数在运行时会被多次计算。C++代码里有一些预定义的函数类(这些在数学上其实挺复杂的),还有一些有限的解析能力,但我对这个结构并不满意。
我需要的是算法和函数的计算都要快速,所以把它们都保持为编译后的代码是有好处的(最好是把数学函数做成C++的函数对象)。不过我想到了用Python把整个模拟过程连接起来:用户可以在Python脚本中指定输入参数,同时也可以用Python来实现结果的存储、可视化(用matplotlib)和图形界面。
我知道大多数情况下,可以通过SWIG等工具把C++类暴露出来,但我还有一个问题,关于如何在Python中解析用户定义的数学函数:
有没有办法在Python中构建一个C++函数对象,并把它传递给C++算法?比如,当我在Python中调用
f = WrappedCPPGaussianFunctionClass(sigma=0.5)
WrappedCPPAlgorithm(f)
时,它会返回一个指向C++对象的指针,然后这个指针可以传递给需要这样的指针的C++例程,或者类似的东西……(不过关于内存管理的问题就别问我了 :S)
关键是算法中不应该有任何对Python代码的回调。之后我想扩展这个例子,在Python端做一些简单的表达式解析,比如函数的和或积,并返回一些复合的、像解析树的C++对象,但现在先从基础开始。
抱歉发了这么长的帖子,提前感谢大家的建议。
1 个回答
我经常做类似的事情。最简单的解决办法,也是我通常选择的方式,因为说实话,我比较懒,就是把你的API简化成类似C语言的API,然后在Python(或者你喜欢的其他语言)之间传递指针。
首先,创建你的类。
class MyFunctionClass
{
public:
MyFunctionClass(int Param)
...
};
class MyAlgorithmClass
{
public:
MyAlgorithmClass(myfunctionclass& Func)
...
};
然后,创建一组C风格的函数,用来创建和销毁这些类。我通常会把它们简化成传递void*,因为我用的语言本来就不太注重类型安全。这样做更简单。只要在实际使用void*之前,确保把它转换回正确的类型就可以了。
void* CreateFunction(int Param)
{
return new MyFunctionClass(Param);
}
void DeleteFunction(void* pFunc)
{
if (pFunc)
delete (MyFunctionClass*)pFunc;
}
void* CreateAlgorithm(void* pFunc)
{
return new MyAlgorithmClass(*(MyFunctionClass*)pFunc)
}
void DelteAlgorithm(void* pAlg)
{
if (pAlg)
delete (MyAlgorithmClass*)pAlg;
}
现在你只需要让Python调用这些C风格的函数。实际上,它们可以(而且应该)是extern "c"的函数,这样链接起来会更简单。