在Python中使用ctypes可以通过传递指向数组第一个元素的指针自由地将数组传递给C函数,因为在C中,数组会衰减成指向其第一个元素的指针。 因此,对于C函数签名:
void insert_sort(int A[], size_t length);
我可以实现以下Python包装器。
import ctypes
from typing import List, Callable
def wrap_function(lib: ctypes.CDLL, name: str, restype: object, argtypes: List[object]) -> Callable:
"""Simplify wrapping ctypes functions"""
func = lib.__getattr__(name)
func.restype = restype
func.argtypes = argtypes
return func
lib = ctypes.CDLL("path/to/library.so")
insert_sort = wrap_function(lib, 'insert_sort', None, [ctypes.POINTER(ctypes.c_int), ctypes.c_size_t])
但是 C 也允许创建数组的数组,以及更为灵活的大小可变的数组。例如下面的 C 函数签名展示了这个特性。
void matrix_multiply(size_t n, int A[n][n], int B[n][n], int C[n][n]);
这个函数应该如何包装?为了明确我的问题,下面的空白处填什么?
matrix_multiply = wrap_function(lib, 'matrix_multiply', None, [...What goes here...])
如果数组的大小已知,我们可以简单地编写如下代码:
matrix_multiply = wrap_function(lib, 'matrix_multiply', None, [
ctypes.c_size_t, ((ctypes.c_int * 4)*4), ((ctypes.c_int * 4)*4), ((ctypes.c_int * 4)*4)
])
对于大小为4的数组,我们可以怎样做呢?但是当我们不知道这个数字时,我们该怎么办呢?
void matrix_multiply(size_t n, int A[n][n], int B[n][n], int C[n][n]){}
。重点是让Python对任意输入数组运行它。 - Ivor Denham-Dyson