简体   繁体   English

使用SWIG从C向Python返回列表

[英]Return list using SWIG from C to Python

I have the following C function which I'm trying to SWIG-ify: 我具有以下要尝试SWIG验证的C函数:

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

which I want to call in Python and access via: 我想在Python中调用并通过以下方式访问:

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

Where I've previously implemented the DCE_ORDER type as 我以前在其中实现DCE_ORDER类型的位置

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

I've found some documentation on similar problems in the SWIG documentation , but I haven't had any luck implementing a solution. 我已经在SWIG文档中找到了一些有关类似问题的文档 ,但是我并没有实现任何解决方案的运气。 I've also looked into some other stackoverflow questions ( this one seems suspiciously close), also to no avail. 我也研究了其他一些stackoverflow问题( 这个问题似乎很接近),也无济于事。 I suspect that I should use a typemap here, but am young and foolish when it comes to SWIG. 我怀疑我应该在这里使用一个typemap,但是谈到SWIG时,我又年轻又愚蠢。

Any suggestions or pointers? 有什么建议或指示吗?

Many thanks. 非常感谢。

Ended up solving this a couple days later. 几天后解决了这个问题。 If you have a vector that you want to get out you can do something like: 如果您有想要传播的媒介,可以执行以下操作:

%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);
  }
}

And then can access this function through Python as I requested above. 然后可以按照我上面的要求通过Python访问此函数。 Additionally, if you have another function that you want to pass a list into (a getter/setter pair of functions), you can use the following code: 此外,如果您要将列表传递到另一个函数(一对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;
}

which would allow you to pass in a list. 这将允许您传递列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM