python - 如何包装一个 C 函数,该函数返回一个指向带有 ctypes 的 malloc 数组的指针?

标签 python c ctypes

我有一个 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 函数的原型(prototype),以便 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

关于python - 如何包装一个 C 函数,该函数返回一个指向带有 ctypes 的 malloc 数组的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63540036/

相关文章:

python - icon_clock.gif 和 icon_calender.gif 的 django static admin 404

c - 从 RubyMotion 访问 C 结构

c - 为什么 fork 我的进程导致文件被无限读取

python - 我无法使用 ctypes 访问 C++ 类属性

python - Django - TypeError - save() 得到了一个意外的关键字参数 'force_insert'

python - SWIG Python - 包装一个需要双指针指向结构的函数

python - 无法在 python 中的 tkinter arc 中填充颜色。

c - 在这个 if 条件下我要问什么?

python ctypes 和 C++ 指针

python - 通过 Ctypes 从 C 到 Python - 将函数指针的结构包装到静态函数