Моя библиотека создана из simulink и выглядит следующим образом:
lib.h
extern double *params1;
extern double *params2;
typedef struct {
unsigned int params1_len;
unsigned int params2_len;
} P_model_T;
lib. c
double *params1;
double *params2;
P_model_T model_params = { 0, 0 };
void step(double in, double *out) {
// some code using the parameter arrays
}
Я намерен использовать его с python следующим образом, предполагая, что set_params
всегда будет вызываться до вызова функции step
(таким образом, инициализируя необходимые массивы параметров):
lib_wrapper.py
from ctypes import *
import numpy as np
class LibWrapper:
def __init__(self):
self._library = CDLL("lib.dll")
self._param_struct = ModelParameters.in_dll(self._library, 'model_params')
def step(self, _in):
out = c_double()
self._library.step(c_double(_in), byref(out))
return out
def get_params(self, param_name):
array_len = getattr(self._param_struct, f'{param_name}_len') # get length of parameter array
array_p = POINTER(c_double * array_len).in_dll(self._library, param_name) # get actual array from library
return np.array(array_p.contents) # copy and return
def set_params(self, param_name, data):
array = (c_double * len(data))(*data)
setattr(self._library, param_name, pointer(array))
class ModelParameters(Structure):
_fields_ = [('params1_len', c_uint32),
('params2_len', c_uint32)]
Мой вопрос касается реализации set_params
: насколько я понимаю, мое решение не присваивает адрес array
моему фактическому params1
/ params2
переменная в dll, но она изменяет только представление dll внутри ctypes. Из-за этого я всегда получаю нарушение прав доступа при вызове моей функции step
, поскольку мои переменные параметров по-прежнему указывают на 0x0000000000000000.
Как правильно назначить выделенный массив для params
переменных в общей библиотеке?
Последующие действия: будет ли более чистый способ написать мою get_params
? Может ли ctypes каким-то образом «запомнить» тип моих переменных params
после того, как я их установил, чтобы мне не нужно было приводить их?