gpt4 book ai didi

python - 如何将结构内部的 numpy 数组传递给 ctypes 函数?

转载 作者:太空宇宙 更新时间:2023-11-04 03:47:02 24 4
gpt4 key购买 nike

我正在尝试从我的 Python 应用程序中的库中包装一些第三方代码。本质上,我想调用的函数采用一个结构作为输入,其中包含(除其他外)指向 double 组的指针。一个简化的例子是:

myfunc.h:

typedef struct mystruct_t {
int n;
double *x;
} mystruct_t;

double myfunc(mystruct_t* data);

myfunc.c:

#include "myfunc.h"

double myfunc(mystruct_t* data) {
double result = 0.;
for(int i = 0; i < data->n; i++) {
result += data->x[i];
}
return result;
}

生成文件:

CC = gcc
CFLAGS = -g -Wall -fPIC -lm -std=gnu99

all: libmyfunc.so

m.PHONY : clean

libmyfunc.so: myfunc.o
gcc -shared -Wl,-soname,$@ -o $@ $^

%.o: %.c
$(CC) -c $(CFLAGS) $<

clean:
rm -vf libmyfunc.so *.o

我想使用 NumPy、ctypes.Structurenumpy.ctypeslib 包装 myfunc,这样我就可以将 NumPy 数组传递给 myfunc 作为 mystruct_t 的属性。到目前为止,我一直在尝试以下操作:

myfunc.py:

#!/usr/bin/env python
import numpy as np
import numpy.ctypeslib as npct
import ctypes
import os

array_1d_double = npct.ndpointer(dtype=np.double, ndim=1, flags='C_CONTIGUOUS')


class MyStruct(ctypes.Structure):
_fields_ = [
('n', ctypes.c_int16),
('x', array_1d_double)
]

libmyfunc = npct.load_library('libmyfunc', os.path.dirname(__file__))
libmyfunc.myfunc.restype = ctypes.c_double
libmyfunc.myfunc.argtypes = [
ctypes.POINTER(MyStruct)
]

x = np.array([1.0, 2.0, 3.0, 4.0])

mystruct = MyStruct()
mystruct.n = len(x)
mystruct.x = x

res = libmyfunc.myfunc(mystruct)

但是,此操作失败并显示以下错误消息:

$ python myfunc.py
Traceback (most recent call last):
File "./myfunc.py", line 26, in <module>
mystruct.x = x
TypeError: cannot be converted to pointer

如何正确定义我的函数签名以便进行类型转换?或者在将它分配给 mystruct.x 之前,我是否需要以某种方式转换 x

不幸的是,我无法更改我想调用的方法的签名,而且我希望不必编写包装器 C 代码,除非绝对必要。我在这方面找到的其他问题和资源仅涉及 ctypes.Structurenumpy.ctypeslib,但你能让它们一起工作吗?

我已经上传了我的简化示例 as a gist因此您可以将其用作起点。

非常感谢!

最佳答案

您可以删除 array_1d_double。不需要。

结构应该这样声明:

class MyStruct(ctypes.Structure):
_fields_ = [
('n', ctypes.c_int),
('x', ctypes.POINTER(ctypes.c_double))
]

我已经改变了这两种类型。您有 c_int16,但您在 C 代码中使用的类型是 int。映射到 c_int。同样对于数组,即 double*。在 ctypes 中是 POINTER(ctypes.c_double)

结构应该像这样初始化:

mystruct = MyStruct()
mystruct.n = len(x)
mystruct.x = npct.as_ctypes(x)

通过这些更改,您的代码可以按预期工作。

关于python - 如何将结构内部的 numpy 数组传递给 ctypes 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23247903/

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