Использование 2d-массива в ctypes для вызова методов в C из Python - PullRequest
0 голосов
/ 08 мая 2020

Я написал код, как в Python 2D-массив i C, используя ctypes для вызова функции C в Python, он работает, если я использую тот же код в ссылка , но будет хорошо, если я смогу использовать структуру вместо отдельных переменных. Итак, я изменил код, например, вниз, но он не работает и дает некоторую ошибку, например TypeError: не может быть преобразован в указатель , я не мог найти, где ошибка. Вот мой код. Структура в C.

#define EXTERN extern "C" _declspec(dllexport)

EXTERN typedef struct MLData {
    double** X;
    int *y;
    int *types;
    const int m;
    const int n;
    int metric;
};

Определение функции в C

EXTERN void compactness(const MLData* data);

Python код, который вызывает C

_doublepp = ndpointer(dtype=np.uintp, ndim=2, flags='C')

cml = CDLL(r"D:\Nuu\AI\Programms\C\Machine Learning\Debug\Machine Learning.dll")

class MLData(Structure):
    _fields_= [
        ('X', _doublepp),
        ('y', POINTER(c_int)),
        ('types', POINTER(c_int)),
        ('m', c_int),
        ('n', c_int),
        ('metric', c_int)
    ]

def converting(X, y, types):
    return (X.__array_interface__['data'][0]
      + np.arange(X.shape[0])*X.strides[0]).astype(np.uintp), \
           y.ctypes.data_as(POINTER(c_int)), \
            types.ctypes.data_as(POINTER(c_int))
def compactness(X, y, types = None, metric = 1):

    if types is None:
        types = np.full(shape=(X.shape[1]), fill_value=1)

    X_c, y_c, types_c = converting(X, y, types)

    data = MLData(X_c, y_c, types_c, X.shape[0], X.shape[1], metric)

    foo = cml.compactness
    foo.argtypes = [POINTER(MLData)]
    foo.restype = POINTER(c_double)

    return foo(data)

X, y и типы: numpy массив.

...