使用Boost.Python将Python函数转换为C++函数

8 投票
1 回答
1001 浏览
提问于 2025-04-16 05:34

我有一堆用C++写的类和API,然后通过Boost.Python让它们可以在Python中使用。

我现在在研究创建以下架构的可能性。
在Python中:

from boostPythonModule import *
AddFunction( boostPythonObject.Method1, args )
AddFunction( boostPythonObject.Method2, args )
AddFunction( boostPythonObject.Method2, args )
RunAll( ) # running is done by C++

在C++中:

void AddFunction( boost::object method,  boost::object args )
{
    /// 1. Here i need to extract a real pointer to a function
    /// 2. Make argument and type checking for a function under method
    /// 3. Unpack all arguments to native types
    /// 4. Store the pointer to a function somewhere in local storage
}

void RunAll( )
{
    /// 1. run all previously stored functions and arguments for them
}

基本上,我想把所有的功能都放到我程序的本地部分。问题是,我不确定是否能从Boost的元信息中提取出所有需要的数据,以便以通用的方式做到这一点——在编译时我并不知道我会调用哪些函数,以及它们接受什么参数。

有几个问题:
1. 有没有共享的Python信息表可以让我访问,以检查一些相关内容?
2. Boost.Python会进行参数类型检查。这部分可以单独重用吗?

请告诉我你的想法。

谢谢

1 个回答

1

我会考虑在Python层面上缓存函数和它们的参数,也就是说,先保存参数,使用教程中关键字参数的最新形式,然后再调用你的C++函数,之后再解包保存的参数。在Python层面进行解包可以避免任何与Boost类型安全相关的复杂问题(所有的类型检查都会在RunAll阶段进行,这样会让速度变慢,也不太安全)。

为了提高速度,优化的方法是实现一个C++类,提供一个通用接口,能够接受支持特定参数的函数调用,并在内部缓存这些值,以便在后续运行中使用。

struct Runner {
  virtual int run() = 0;
};

struct ConcreteRunner: public Runner {
  std::string _arg;
  void setArguments(std::string arg) {_arg=arg;}
  virtual int run() {clog << "ConcreteRunner is called with argument" << _arg << endl;}
};

这种方法在RunAll部分之外处理参数解析,因此可以尽可能快。

撰写回答