python - 如何使用 python 变量而不是硬编码值创建 ctypes 变量?

标签 python c ctypes

创建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函数原型(prototype)

// 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__ attribute(如果您熟悉其中任何一个)。 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 字典中。例如,在这种情况下,var8 中的数组只是复制到缓冲区中,因此 c_parameters 不需要保存对原始数组的引用。

关于python - 如何使用 python 变量而不是硬编码值创建 ctypes 变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18691035/

相关文章:

python - : Python, ctypes.windll.user32.SystemParametersInfoA 中的参数是什么?

python - Pymongo 或 Mongodb 将两个相等的 python 字典视为不同的对象。我可以强制他们受到同样的对待吗?

python - 循环到占位符文本 block 并连接每个文本 block

c - K&R 第 5.11 节中的排序程序

Python3 int, long统一实现

python - 将哪种类型的 ctype 指针传递给 NI IMAQ 的 imgBayerColorDecode?

javascript - 使用 javascript-ajax Django 在 <a> html 中获取特定值

Python - 错误 : look-behind requires fixed-width pattern

c++ - 在macOS Catalina上编译Intel MKL CBLAS示例文件的问题

python - 为什么这个 Delphi DLL 在从 Python 调用时抛出 WindowsError?