[英]How to creating ctypes variables using python variables instead of hard-coded values?
创建ctypes
变量时,是否可以不使用python变量传递值?
我在调用共享C库的地方有一些代码。 如果我使用方法1(参见下文)将参数传递给此C库,则一切正常。 但是,如果我使用方法2,则会得到垃圾。 该代码还有其他部分。 但是我已经确认,当我用方法1替换方法2时,一切正常。 所以这里有些问题。
如果我在方法2中所做的操作无效,那么如果我想针对给定变量的不同值自动运行代码的过程,该怎么办?
方法1(效果很好)
import ctypes as C
c_thresholds = (C.c_double * 4)()
for idx, value in enumerate(thresholds):
c_thresholds[idx] = value
goodH = Good(C.c_char('H'), C.c_double(0.5), C.c_int(100), C.c_int(20))
goodL = Good(C.c_char('L'), C.c_double(0.5), C.c_int(75), C.c_int(20))
c_parameters = Params(
var1 = C.c_int(100),
var2 = C.c_int(4),
var3 = C.c_int(5),
var4 = C.c_int(5000),
var5 = C.c_char_p("modelname"),
var6 = C.c_double(0.5),
var7 = C.c_double(90),
var8 = c_thresholds,
var9 = C.c_int(2),
H = goodH,
L = goodL
)
runsimulation(c_parameters)
方法2(这不起作用,输出垃圾)
import ctypes as C
def create_cparams(var1, var2, var3, var4, var5, var6, var7, var8, var9):
c_thresholds = (C.c_double * 4)()
for idx, value in enumerate(var8):
c_thresholds[idx] = value
goodH = Good(C.c_char('H'), C.c_double(0.5), C.c_int(100), C.c_int(20))
goodL = Good(C.c_char('L'), C.c_double(0.5), C.c_int(75), C.c_int(20))
c_parameters = Params(
var1 = C.c_int(var1),
var2 = C.c_int(var2),
var3 = C.c_int(var3),
var4 = C.c_int(var4),
var5 = C.c_char_p(var5),
var6 = C.c_double(var6),
var7 = C.c_double(var7),
var8 = c_thresholds,
var9 = C.c_int(var9),
H = goodH,
L = goodL
)
return c_parameters
# These are python variables
var1 = 100
var2 = 4
var3 = 5
var4 = 5000
var5 = "modelname"
var6 = 0.5
var7 = 90
var8 = [1, 0.9, 0.8, 0.7]
var9 = 2
# Calling the create_cparams function defined above
c_parameters = create_cparams(var1, var2, var3, var4, var5, var6, var7, var8, var9)
runsimulation(c_parameters)
如果有帮助的话,Params类是由给定的(在这两种方法中不变):
class Params(C.Structure):
_fields_ = [
("var1", C.c_int),
("var2", C.c_int),
("var3", C.c_int),
("var4", C.c_int),
("var5", C.c_char_p ),
("var6", C.c_double),
("var7", C.c_double),
("var8", (C.c_double * 4) ),
("var9", C.c_int),
("H", Good),
("L", Good)
]
C函数原型
// runsimulation() function above calls this C function
void run_multiple_reps (struct params parameters, struct repdata *data,
int len_timepdsarr, int *timepdsarr)
// params struct on C side, which Params class duplicates
struct params
{
int var1;
int var2;
int var3;
int var4;
char *var5;
double var6;
double var7;
double var8[4];
int var9;
struct good H;
struct good L;
};
Structure
的字段属性是CField
描述符对象。 如果您熟悉描述符,则描述符就像Python property
或__slots__
属性。 CField
知道字段的数据类型及其在缓冲区中的偏移量。 每个C数据类型都有一个关联的get / set函数,该函数在Python对象之间来回转换。 因此,通常您可以将Python对象直接分配给该字段。 例如:
thresholds = [1, 0.9, 0.8, 0.7]
c_parameters = Params(
var1 = 100,
var2 = 4,
var3 = 5,
var4 = 5000,
var5 = "modelname",
var6 = 0.5,
var7 = 90,
var8 = (C.c_double * 4)(*thresholds),
var9 = 2,
H = Good('H', 0.5, 100, 20),
L = Good('L', 0.5, 75, 20),
)
如果ctypes需要保留对Python对象的引用以使其保持活动状态,则该引用将存储在Structure
的_objects
dict中。 例如,在这种情况下,只需将var8
的数组复制到缓冲区中,因此c_parameters
不需要保留对原始c_parameters
的引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.