簡體   English   中英

如何將結構從 python 傳遞到共享 object 中的 ctypes function?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM