本文介绍了python的swig typemap:输入和输出数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个要在 Python 中使用的 C 函数:

I have a C function I want to use in Python:

extern int convertAtoB( stateStruct *myStruct,
                        const double PointA[3],
                        double PointB[3]);

使用 SWIG,我想我需要定义一个类型映射来转换两个点(PointA 是输入,PointB 是输出),以便 Python 可以使用它.typemaps.i 中似乎没有与此相关的类型映射,因此我必须定义一个.我似乎无法在 SWIG 文档中找到有关数组的示例.

Using SWIG, I think I need to define a typemap to convert the two points (PointA the input, PointB the output) so that Python can use it. There doesn't seem to be a typemap in typemaps.i that works with this, so I have to define one. I can't seem to find examples of this for arrays in the SWIG documentation.

我想像这样使用这个库:

I would like to use this library like so:

s = externalStruct()
point_a = [1, 2, 3]
result, point_b = convertAtoB(s, point_a)
print point_b
"expect [4, 5, 6]"

我该怎么做?谢谢

推荐答案

这是我找到的一个解决方案,但它可能不是最好的:

Here's one solution I found, but it might not be the best:

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

这是我最终遇到的文档中的一个示例,该示例将 Python 列表转换为数组.下一部分更难,拼凑几个例子我可以将返回数组转换为python列表:

This is an example in the documents I finally came across which convert Python lists into arrays. The next part was harder, piecing together several examples I could convert the return array into a python list:

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

但是,我必须为 API 中的每个返回值创建其中一个.另外我必须用一个虚拟值作为参数来调用它:

However, I have to create one of these for every return value in the API. Also I have to call it with a dummy value as a parameter:

point_b = convertAtoB(s, point_a, dummy)

有没有更好的方法?

这篇关于python的swig typemap:输入和输出数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 22:54