gpt4 book ai didi

python - SWIG+c+Python : Passing and receiving c arrays

转载 作者:搜寻专家 更新时间:2023-10-31 02:17:01 25 4
gpt4 key购买 nike

我正在尝试通过 SWIG 和 Python 重用一些旧的 C 代码。现在我很困惑。我得到的错误可以用一个小例子来证明:

bsp.h:

extern void add(int a[], int b[], int c[]);

bsp.c:

#include "bsp.h" 
void add(int a[], int b[], int c[])
{
c[0] = a[0] + b[0];
c[1] = a[1] + b[1];
}

bsp.i

%module bsp
%{
#include "bsp.h";
%}
%include "bsp.h";

设置.py:

#!/usr/bin/env python

from distutils.core import setup, Extension

bsp_module = Extension('_bsp',
sources = ['bsp_wrap.c', 'bsp.c']
)

setup(name = 'bsp',
ext_modules = [bsp_module],
py_modules = ["bsp"]
)

示例 Python 文件“pybsp.py”:

import bsp

a = [1, 1]
b = [1, 1]
c = []

bsp.add(a, b, c)

print(c)

我得到了错误:

Traceback (most recent call last):
File "pybsp.py", line 31, in <module>
bsp.add(a, b, c)
TypeError: in method 'add', argument 1 of type 'int []'

现在,我感到困惑的是 SWIG Documentation说:“SWIG 完全支持 C/C++ 指针。此外,SWIG 可以处理不完整的类型信息。”

我也试过添加

%apply int * INPUT { int *a}
%apply int * INPUT { int *b}
%apply int * OUTPUT { int *c}

我的 .i 文件,在这种情况下被推荐,但没有成功。我的猜测是,我必须在 Python 中创建一个类似于对象的指针才能传递,但我不知道它是如何工作的,但我也希望有一种更简单的方法。

非常感谢您的帮助!

P.S.:如您所料,这是我第一次接触 SWIG,因此很遗憾,我无法从看似相似的问题的解决方案中推导出解决方案。

编辑:我发现对于具有给定维度的数组,如上所述,NumPy 似乎是避免手动包装的好选择。给出了基本的例子here.因此,我将函数定义更改为

void add(int* a, int dim_a, int *b, int dim_b, int *c, int dim_c)

现在包装器似乎有机会将 NumPy 数组转换为 C 数组。

i-文件

%module bsp
%{
#define SWIG_FILE_WITH_INIT
#include "bsp.h"
%}

%include "numpy.i"

%init %{
import_array();
%}

%apply (int* IN_ARRAY1, int DIM1){(int* a, int dim_a), (int* b, int dim_b)}
%apply (int* ARGOUT_ARRAY1, int DIM1){(int* c, int dim_c)}

%include "bsp.h"

setup.py

#!/usr/bin/env python

from distutils.core import setup, Extension
import numpy

try:
numpy_include = numpy.get_include()
except AttributeError:
numpy_include = numpy.get_numpy_include()

bsp_module = Extension('_bsp',
sources=['bsp_wrap.c', 'bsp.c'],
include_dirs=[numpy_include]
)

setup(name='bsp',
ext_modules=[bsp_module],
py_modules=["_bsp"]
)

最后是 python 脚本,我想在其中使用 int32 来避免来自 NumPy 的类型转换错误(int64 -> int32)

import bsp
import numpy as np
a = np.array([1, 1], dtype=np.int32)
b = np.array([1, 1], dtype=np.int32)
c = np.array([1, 1], dtype=np.int32)

bsp.add(a, b, c)

print(c)

现在我摆脱了以前的错误,但我有一个新错误:

  File "pybsp.py", line 10, in <module>
bsp.add(a, b, c)
TypeError: Int dimension expected. 'unknown type' given.

有什么建议吗?

最佳答案

好的,现在我知道了。正如上面编辑中所写,使用 numpy.i 可以很舒服地包装数组。我没有看到的是,ARGOUT 数组不需要数组作为输入,就像在 C 中一样。只需要维度。因此,使用上面的代码,脚本

import bsp
import numpy as np
a = np.array([1, 1], dtype=np.int32)
b = np.array([1, 1], dtype=np.int32)

c = bsp.add(a, b, np.shape(a)[0])

print(c)

给出想要的输出

[2 2]

关于python - SWIG+c+Python : Passing and receiving c arrays,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36222455/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com