Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python的swig类型映射:输入和输出数组_Python_C_Swig - Fatal编程技术网

python的swig类型映射:输入和输出数组

python的swig类型映射:输入和输出数组,python,c,swig,Python,C,Swig,我想在Python中使用一个C函数: extern int convertAtoB( stateStruct *myStruct, const double PointA[3], double PointB[3]); 使用SWIG,我想我需要定义一个类型映射来转换两点:输入点a,输出点b,以便Python可以使用它。typemaps中似乎没有一个typemap。我认为这是可行的,所以我必须定义一个。

我想在Python中使用一个C函数:

extern int convertAtoB( stateStruct *myStruct,
                        const double PointA[3],
                        double PointB[3]);
使用SWIG,我想我需要定义一个类型映射来转换两点:输入点a,输出点b,以便Python可以使用它。typemaps中似乎没有一个typemap。我认为这是可行的,所以我必须定义一个。在SWIG文档中,我似乎找不到有关数组的示例

我想这样使用这个库:

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

我该怎么做?谢谢

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

%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签名中的伪参数,您需要将PointB[3]的%typemapin更改为%typemapin,numinputs=0,以指示SWIG忽略该输入值—您已经在复制它了。这将从python方法签名中删除伪参数

但是,我不确定是否需要为该专门化复制整个%typemapin。也许有一种方法可以重用实际的类型映射,但我不知道如何重用。否则你会得到额外的钱

%typemap(in,numinputs=0) double PointB[3] (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;
}

这是一个古老的主题,但我回答它,因为没有太多关于SWIG的帖子被回答

具体针对上述情况

%typemap(in, numinputs=0) double PointB[3] {
  double tmp[3];
  $1 = tmp;
}

%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;
}
%typemap(in,numinputs=0) double PointB[3] (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;
}
%typemap(in, numinputs=0) double PointB[3] {
  double tmp[3];
  $1 = tmp;
}

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