如何解决您如何包装一个C函数,该函数使用ctypes返回指向malloc数组的指针?
我有一个C函数,该函数读取二进制文件并返回动态大小的无符号整数数组(大小基于二进制文件中的元数据):
//example.c
#include <stdio.h>
#include <stdlib.h>
__declspec(dllexport)unsigned int *read_data(char *filename,size_t* array_size){
FILE *f = fopen(filename,"rb");
fread(array_size,sizeof(size_t),1,f);
unsigned int *array = (unsigned int *)malloc(*array_size * sizeof(unsigned int));
fread(array,sizeof(unsigned int),*array_size,f);
fclose(f);
return array;
}
此answer似乎是在说将创建的数组从C传递到Python的正确方法是这样的:
# example_wrap.py
from ctypes import *
import os
os.add_dll_directory(os.getcwd())
indexer_dll = CDLL("example.dll")
def read_data(filename):
filename = bytes(filename,'utf-8')
size = c_size_t()
ptr = indexer_dll.read_data(filename,byref(size))
return ptr[:size]
但是,当我运行python包装程序时,代码在ptr[:size]
处静默失败,就好像我试图越界访问数组一样,也许是,但是传递此内容的正确方法是什么?动态调整数组大小?
解决方法
一些注意事项:
首先,您需要正确设置C函数的原型,以便ctypes可以在C和Python类型之间正确转换。
第二,由于size
实际上是ctypes.c_size_t
对象,因此实际上您需要使用size.value
来访问数组大小的数值。
第三,由于ptr[:size.value]
实际上将数组内容复制到Python列表中,因此您将要确保也free()
分配的C数组,因为您将不再使用它。
(在这里将数组复制到Python列表可能不理想,但我认为在这里还可以,因为否则在Python中处理C数组会更加复杂。)
这应该有效:
from ctypes import *
import os
os.add_dll_directory(os.getcwd())
indexer_dll = CDLL("example.dll")
indexer_dll.read_data.argtypes = [c_char_p,POINTER(c_size_t)
indexer_dll.read_data.restype = POINTER(c_int)
libc = cdll.msvcrt
def read_data(filename):
filename = bytes(filename,'utf-8')
size = c_size_t()
ptr = indexer_dll.read_data(filename,byref(size))
result = ptr[:size.value]
libc.free(ptr)
return result
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。