【问题标题】:Return list using SWIG from C to Python使用 SWIG 从 C 到 Python 返回列表
【发布时间】:2014-04-29 00:27:33
【问题描述】:

我有以下 C 函数,我正在尝试 SWIG-ify:

void    GetAttOrder(int node, DCE_ORDER order, float att[3]);

我想在 Python 中调用并通过以下方式访问:

node = 0; order = DCD_TYPR;
attitude = GetAttOrder(node, order);
attitude[0] // 45.232

我之前将 DCE_ORDER 类型实现为

typedef enum
{
  DCD_TPYR = 0,
  DCD_TYPR,
  DCD_TYRP,
  ...
  DCD_PRYT
} DCE_ORDER;

我在SWIG documentation 中找到了一些关于类似问题的文档,但我没有任何运气来实施解决方案。我还研究了其他一些 stackoverflow 问题(this one 似乎很接近),也无济于事。我怀疑我应该在这里使用 typemap,但在 SWIG 方面我还年轻又愚蠢。

有什么建议或指点吗?

非常感谢。

【问题讨论】:

  • 您是否尝试过创建一个调用您的GetAttOrder 的重载float* GetAttOrder(int node, DCE_ORDER order)?我相信 SWIG 知道如何将指针返回视为 Python 列表。
  • 不,我没有尝试过,但我确实得到了一些工作。我会继续自己回答。

标签: python c swig


【解决方案1】:

几天后解决了这个问题。如果您有一个想要取出的向量,您可以执行以下操作:

%typemap(in, numinputs=0) float vec3out[3] (float temp[3]) {
  $1 = temp;
}

%typemap(argout) float vec3out[3] {
  int i;
  $result = PyList_New(3);
  for (i = 0; i < 3; i++) {
    PyObject *o = PyFloat_FromDouble((double) $1[i]);
    PyList_SetItem($result,i,o);
  }
}

然后可以按照我上面的要求通过 Python 访问这个函数。此外,如果您想要将列表传递给另一个函数(一对 getter/setter 函数),您可以使用以下代码:

%typemap(in) float vec3in[3] (float temp[3]) {
  int i;
  if (!PySequence_Check($input)) {
    PyErr_SetString(PyExc_ValueError,"Expected a sequence");
    return NULL;
  }
  if (PySequence_Length($input) != 3) {
    PyErr_SetString(PyExc_ValueError,"Size mismatch. Expected 3 elements");
    return NULL;
  }
  for (i = 0; i < 3; i++) {
    PyObject *o = PySequence_GetItem($input,i);
    if (PyNumber_Check(o)) {
      temp[i] = (float) PyFloat_AsDouble(o);
    } else {
      PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers");
      return NULL;
    }
  }
  $1 = temp;
}

这将允许您传入一个列表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多