使用ctypes覆盖库中的可访问结构

时间:2018-01-20 19:39:55

标签: python memory struct ctypes

我想在Python中使用C库,我使用ctypes来做到这一点。

我定义了我想在库中访问的结构,我想在我的Python程序中创建这些结构的多个实例,并用其中一个实例覆盖C库中的结构,让它计算然后覆盖它与实例中的另一个。 基本上我想用其他参数覆盖链接到库的结构的 fields ,而不必手动更改每个参数。

示例:

from ctypes import *

class Example(Structure):
    _pack_ = 1
    _fields_ = [("One", c_uint8),
                ("Two", c_double),
                ("Three", c_double)]


lib = cdll['./test.dll']
libInit = lib['init']
libStep = lib['step']
libClose = lib['close']

libInit()

In1 = Example
In1.One = 2
In1.Two = 10
In1.Three = 23

In2 = Example
In2.One = 3
In2.Two = 4
In2.Three = 50

In = Example.in_dll(lib, "Example")
In = In1

libStep()

Out = Example.in_dll(lib, "Example")

In = In2

libStep()

Out = Example.in_dll(lib, "Example")

libClose()

我知道像我在示例中所做的那样覆盖In参数并不起作用,因为它删除了指向C库的链接。有没有办法以某种方式覆盖它?

1 个答案:

答案 0 :(得分:0)

在Structure类中创建一些帮助器。您必须修改in_dll变量,但可以更轻松:

<强> test.c的

#include <stdint.h>
#include <stdio.h>

#pragma pack(push,1)
__declspec(dllexport) struct Example
{
    uint8_t One;
    double Two;
    double Three;
} Example;
#pragma pack(pop)

__declspec(dllexport) void libInit()
{
}

__declspec(dllexport) void libStep()
{
    Example.One += 1;
    Example.Two += 2;
    Example.Three += 3;
}

__declspec(dllexport) void libClose()
{
}

的Python:

from ctypes import *

class Example(Structure):
    _pack_ = 1
    _fields_ = [("One", c_uint8),
                ("Two", c_double),
                ("Three", c_double)]
    def set(self,a,b,c):
        self.One = a
        self.Two = b
        self.Three = c
    def __repr__(self):
        return 'Example({},{},{})'.format(self.One,self.Two,self.Three)

lib = CDLL('test')

libInit = lib.libInit
libInit.argtypes = None
libInit.restype = None

libStep = lib.libStep
libStep.argtypes = None
libStep.restype = None

libClose = lib.libClose
libClose.argtypes = None
libClose.restype = None

example = Example.in_dll(lib,'Example')

libInit()
example.set(1,2,3)
print(example)
libStep()
print(example)
libStep()
print(example)
example.set(2,2,2)
libStep()
print(example)
libClose()

输出:

Example(1,2.0,3.0)
Example(2,4.0,6.0)
Example(3,6.0,9.0)
Example(3,4.0,5.0)