c++ - 有没有办法使用 SWIG 将不同的数组类型从 python 传递到 c++?

标签 c++ python c numpy swig

我想使用输入 double 组和整数数组的 SWIG 将 C++ 函数传递给 python。有办法做到这一点吗?

例如,我有一个接受 double 和 int 数组的 c++ 函数:

double myfun(double* a, int n, int* b, int m){...}

在我尝试编写的 SWIG 接口(interface)文件中

%apply (double* IN_ARRAY1, int DIM1, int* IN_ARRAY1, int DIM1) {(double* a, int n, int* b, int m)}

但运气不好。它编译了,但我无法像

这样在 python 中调用 myfun 函数
myfun(a,b) 

其中 a 是 double numpy 数组,b 是整型 numpy 数组。我在 python 中收到以下错误:

myfun() takes exactly 4 arguments (2 given)

有什么建议吗?这可能吗?

谢谢!

最佳答案

简短的回答是,您需要使用一个接受两个输入的类型映射,但将 numinputs 属性设置为 1,例如:

%module test

%typemap(in,numinputs=1) (double *a, size_t) %{
  assert(PyList_Check($input));
  $2 = PyList_Size($input);
  $1 = malloc(sizeof *$1 * $2);
  for(size_t i = 0; i < $2; ++i) {
    $1[i] = PyFloat_AsDouble(PyList_GetItem($input, i));
  }
%}

%typemap(in, numinputs=1) (int *b, size_t) %{
  assert(PyList_Check($input));
  $2 = PyList_Size($input);
  $1 = malloc(sizeof *$1 * $2);
  for (size_t i = 0; i < $2; ++i) {
    $1[i] = PyInt_AsLong(PyList_GetItem($input, i));
  }
%}

%typemap(freearg) (double *a, size_t) %{
  free($1);
%}

%typemap(freearg) (int *b, size_t) %{
  free($1);
%}

%inline %{
  double myfun(double *a, size_t n, int *b, size_t m) {
    (void)a; (void) b;
    printf("%d, %d\n", n, m);
    for (size_t i = 0; i < (n > m ? n : m); ++i) {
      printf("%d: %f - %d\n", i, i < n ? a[i] : 0, i < m ? b[i] : 0);
    }
    return 1.0;
  }
%}

这行得通,每对 (array, len) 都有一个类型映射,足以用作:

import test

a = [0.5, 1.0, 1.5]
b = [1,2,3]

test.myfun(a,b)

我们本可以使用 alloca 或 C99 的 VLA 功能来避免调用 malloc,但出于说明目的,这是可行的。

(注意:您没有在函数原型(prototype)的任何地方编写 const,但这意味着它没有修改输入数组。如果不是这种情况,那么您需要编写一个相应的 argout 类型映射从分配的数组中复制,返回到 Python 列表中)。

然而,它也是相当重复的,所以如果我们可以在两者之间共享一些代码可能会更好 - 如果需要,您可以使用一些更高级的 SWIG 功能来做到这一点。您还可以添加对 memory views 的支持作为输入,而不是仅在需要时列出。

关于c++ - 有没有办法使用 SWIG 将不同的数组类型从 python 传递到 c++?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17535948/

相关文章:

Python (flask) BLOB 图像、SQLite、Sqlalchemy - 显示图像

c - [C] : Segmentation fault using strcpy() into String Arrays

python - 如何从终端传递有编码问题的字符串参数?

c++ - 解决二维数组中的迷宫

c++ - VC++ Glew 外部链接错误

c++ - 当一个函数有一个特定大小的数组参数时,为什么它被替换为一个指针?

python - 将图像数据从 pandas 加载到 pytorch

c - 将波形文件数据加载到缓冲区

c - 为什么我的程序在 for 循环后没有打印正确的值?

c++ - 是否可以为每个循环删除 c++11 中 std::list 的元素