【问题标题】:exposing method with unsigned char & argument using Boost.Python使用 Boost.Python 公开带有无符号字符和参数的方法
【发布时间】:2012-10-16 14:24:03
【问题描述】:

我有一个闭源 C++ 库,它提供的头文件代码相当于:

class CSomething
{
  public:
      void getParams( unsigned char & u8OutParamOne, 
                      unsigned char & u8OutParamTwo ) const;
  private:
      unsigned char u8OutParamOne_,
      unsigned char u8OutParamTwo_,
};

我正在尝试将它暴露给 Python,我的包装代码是这样的:

BOOST_PYTHON_MODULE(MySomething)
{
    class_<CSomething>("CSomething", init<>())
        .def("getParams", &CSomething::getParams,(args("one", "two")))

}

现在我正在尝试在 Python 中使用它,但失败了:

one, two = 0, 0
CSomething.getParams(one, two)

结果:

ArgumentError: Python argument types in
    CSomething.getParams(CSomething, int, int)
did not match C++ signature:
    getParams(CSomething {lvalue}, unsigned char {lvalue} one, unsigned char {lvalue} two)

我需要在 Boost.Python 包装器代码或 Python 代码中进行哪些更改才能使其正常工作?如何添加一些 Boost.Python 魔法以自动将 PyInt 转换为 unsigned char 或反之亦然?

【问题讨论】:

  • 这两个参数是 Python 没有的引用,请参见 question
  • @martineau:但我无法改变这一点,所以必须有办法解决这个问题
  • 好的,this 答案有一个解决方法。
  • 你看过call policies吗?如果您必须使用引用,请尝试使用 return_internal_reference 或 return_value_policy
  • @martineau, @georgesl:你们都专注于参考问题,而错误是关于 intunsigned char 之间的不匹配。

标签: c++ python boost-python


【解决方案1】:

Boost.Python 抱怨缺少 lvalue 参数,这是 Python 中不存在的概念:

def f(x):
  x = 1

y = 2
f(y)
print(y) # Prints 2

f 函数的x 参数不是类似 C++ 的引用。在 C++ 中,输出是不同的:

void f(int &x) {
  x = 1;
}

void main() {
  int y = 2;
  f(y);
  cout << y << endl; // Prints 1.
}

你有几个选择:

a) 包装 CSomething.getParams 函数以返回新参数值的元组:

one, two = 0, 0
one, two = CSomething.getParams(one, two)
print(one, two)

b) 包装CSomething.getParams 函数以接受类实例作为参数:

class GPParameter:
  def __init__(self, one, two):
    self.one = one
    self.two = two

p = GPParameter(0, 0)
CSomething.getParams(p)
print(p.one, p.two)

【讨论】:

  • 我已经做了一种解决方案 a) 的变体,但是我创建了两个单独的返回 unsigned char 的 getter,而不是一个返回元组的 getter,并将它们绑定为 Boost.Python 中的属性。
  • @vartec:听起来你的版本至少有两倍——甚至更多——函数调用开销。
  • @martineau:确实如此。但是,它与应用程序完全无关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多