[英]What methods can I use to return a struct to a Python Ctypes call to the function in a shared object?
[英]How to pass a struct from python to a ctypes function in a shared object?
我正在嘗試創建類似於 numpy 的東西來了解 ctypes 的工作原理,但在將指向“Matrix”結構的指針傳遞給某些函數時遇到了問題。
調用 print_matrix 的 output 總是一些隨機的 integer 然后是幾個空格。
I'm using Python 3.7.5 and the C code was compiled using: gcc -shared -o libarray.so -fPIC array.c
C 代碼:
typedef struct Matrix {
int *arr;
int *shape;
int dims;
} Matrix;
void print_matrix(Matrix *Mat) {
int num = 1;
for (int i = 0; i < Mat -> dims; i++) {num *= Mat -> shape[i];}
for (int i = 0; i < num; i++) {
printf("%d ", Mat -> arr[i]);
if (Mat -> dims >= 2) {
if (((i + 1) % Mat -> shape[0]) == 0) {
printf("\n");
}
}
}
}
Python 代碼:
import ctypes as cty
class Matrix(cty.Structure):
_fields_ = [("arr", cty.POINTER(cty.c_int)), ("shape", cty.POINTER(cty.c_int)), ("dims", cty.c_int)]
libarray = cty.CDLL("./libarray.so")
print_matrix = libarray.print_matrix
print_matrix.restype = None
print_matrix.argtypes = [Matrix]
mat = Matrix((cty.c_int * 4)(*[1, 2, 3, 4]), (cty.c_int * 2)(*[2, 2]), cty.c_int(2))
print_matrix(mat)
我知道對於這個 function,我可以通過更改 print_matrix 代碼直接傳遞 Matrix 結構,但是由於我的代碼中的一些其他內容,我想主要處理指針。 很抱歉這個奇怪的限制,並提前感謝。
問題是在 C 中,您有void print_matrix(Matrix *Mat)
,但在 Python 中,您有print_matrix.argtypes = [Matrix]
。 Python 正在傳遞一個Matrix
,但 C 期待一個Matrix *
。 你使用哪一個並不重要,但他們必須同意。
如果你想傳遞一個Matrix
,那么留下你的 Python 代碼並將你的 C 代碼更改為:
#include <stdio.h>
typedef struct Matrix {
int *arr;
int *shape;
int dims;
} Matrix;
void print_matrix(Matrix Mat) {
int num = 1;
for (int i = 0; i < Mat.dims; i++) {num *= Mat.shape[i];}
for (int i = 0; i < num; i++) {
printf("%d ", Mat.arr[i]);
if (Mat.dims >= 2) {
if (((i + 1) % Mat.shape[0]) == 0) {
printf("\n");
}
}
}
}
我將Matrix *Mat
更改為Matrix Mat
並將->
更改為.
.
如果你想傳遞一個Matrix *
,那么留下你的 C 代碼並將你的 Python 代碼更改為:
import ctypes as cty
class Matrix(cty.Structure):
_fields_ = [("arr", cty.POINTER(cty.c_int)), ("shape", cty.POINTER(cty.c_int)), ("dims", cty.c_int)]
libarray = cty.CDLL("./libarray.so")
print_matrix = libarray.print_matrix
print_matrix.restype = None
print_matrix.argtypes = [cty.POINTER(Matrix)]
mat = Matrix((cty.c_int * 4)(*[1, 2, 3, 4]), (cty.c_int * 2)(*[2, 2]), cty.c_int(2))
print_matrix(cty.byref(mat))
我將[Matrix]
更改為[cty.POINTER(Matrix)]
並將mat
更改為cty.byref(mat)
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.