我的库是从 simulink 生成的,如下所示:
库文件
extern double *params1;
extern double *params2;
typedef struct {
unsigned int params1_len;
unsigned int params2_len;
} P_model_T;
库文件
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地址分配给 dll 中的实际params1/params2变量,但它只会更改 ctypes 中的 dll 表示。因此,在调用我的step函数时,我总是会遇到访问冲突,因为我的参数变量仍然指向 0x0000000000000000。
将分配的数组分配给params共享库中的变量的正确方法是什么?
跟进:有没有更干净的方式来写 my get_params?ctypes 可以params在我设置变量后以某种方式“记住”我的变量的类型,这样我就不需要强制转换它们了吗?