Python将void指针作为参数传递给C函数(SWIG,Numpy)

时间:2018-08-21 20:17:00

标签: python c numpy pointers swig

我需要将指针从Python传递到C函数。我目前正在尝试使用SWIG,但我准备切换到任何可以解决我的问题的方法:)

为简化我的问题,我在SWIG中编写了这个空的C函数:

extern void myvoidp(void *p);

我已经设置了.i和.c文件,都可以正常编译并且可以在Python中工作。

我想传递一个Numpy数组。我可以这样获取Numpy数据的内存地址

>>> anp = array([1,2,3])
array([1, 2, 3])
>>> anp.ctypes.data
40546992

我可以使用ctypes和numpy将其转换为void *

>>> anp.ctypes.data_as(ctypes.c_void_p)
c_void_p(40546992)

我尝试了无尽的变体。无论我做什么,当我调用C函数时都会收到此错误。

>>> myswig.myvoidp(anp.ctypes.data_as(ctypes.c_void_p))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: in method 'myvoidp', argument 1 of type 'void *'

我不知道如何编写Python / numpy语句,该语句允许我(简单地)将指针传递给C函数。 :-(

1 个答案:

答案 0 :(得分:-1)

我猜您想接收一个指向NumPy数组数据的指针,以便可以从C访问该数组元素。NumPy附带了SWIG support,它易于使用。只需下载numpy.i并将其放在您的项目目录中即可。

只需将C函数的签名从(void *p)更改为(double *data, int length),然后应用NumPy类型映射。

test.i

%module example
%{
#define SWIG_FILE_WITH_INIT
#include <stdio.h>

void myvoidp(double *data, int length) {
    printf("data = [ ");
    for (int i = 0; i < length; ++i) {
        printf("%f ", data[i]);
    }
    printf("]\n");
}
%}

%include "numpy.i"

%init %{
import_array();
%}

%apply (double* IN_ARRAY1, int DIM1) {(double *data, int length)}
void myvoidp(double *data, int length);

test.py

from example import myvoidp
from numpy import array

anp = array([1,2,3])
myvoidp(anp)

示例调用:

$ swig -python test.i
$ clang -Wall -Wextra -Wpedantic -I /usr/include/python3.6m/ -fPIC -shared -o _example.so test_wrap.c -lpython3.6m
$ python3 test.py 
data = [ 1.000000 2.000000 3.000000 ]