我的库是从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
的地址分配给dll中我的实际params1
/ params2
变量,但它仅更改了dll表示形式内部ctypes。因此,当我调用step
函数时,总是遇到访问冲突,因为我的参数变量仍指向0x0000000000000000。
将我分配的数组分配给共享库中的params
变量的正确方法是什么?
跟进:会有更简洁的方式来写我的get_params
吗?设置它们后,ctypes可以以某种方式“记住”我的params
变量的类型,这样就不必强制转换它们了吗?
我的库是从simulink生成的,看起来像这样:lib.h extern double * params1; extern double * params2; typedef struct {unsigned int params1_len; unsigned int params2_len; } ...
我让它正常工作,但这是一个把戏。您的set_params
未按in_dll
查找参数,因此无效。同样,即使使用in_dll
访问内容,也只是试图取消对已经存在的空指针的引用,因此我需要获取参数的地址才能更改空指针。我使用以下DLL和Python代码进行测试: