代码之家  ›  专栏  ›  技术社区  ›  Gabriele

包含数组的CTypes结构

  •  2
  • Gabriele  · 技术社区  · 6 年前

    我想用 ctypes . 我对操作包含数组的C结构很感兴趣。考虑以下内容 my_library.c

    #include <stdio.h>
    
    
    typedef struct {
    
        double first_array[10];
        double second_array[10];
    
    } ArrayStruct;
    
    
    void print_array_struct(ArrayStruct array_struct){
    
        for (int i = 0; i < 10; i++){
            printf("%f\n",array_struct.first_array[i]);
        }
    
    }
    

    假设我在一个共享库中编译了它 my_so_object.so 从巨蟒身上我可以做这样的事

    import ctypes
    from ctypes import *
    
    myLib = CDLL("c/bin/my_so_object.so")
    
    
    class ArrayStruct(ctypes.Structure):
        _fields_ = [('first_array', ctypes.c_int * 10), ('second_array', ctypes.c_int * 10)]
    
        def __repr__(self):
            return 'ciaone'
    
    
    myLib.print_array_struct.restype = None
    myLib.print_array_struct.argtype = ArrayStruct
    
    my_array_type = ctypes.c_int * 10
    x1 = my_array_type()
    x2 = my_array_type()
    
    a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    
    x1[0:9] = a[0:9]
    
    a = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
    
    x2[0:9] = a[0:9]
    
    print(my_array_type)
    >>> <class '__main__.c_int_Array_10'>
    
    print(x1[2])
    >>> 3
    
    print(x2[2])
    >>> 13
    
    x = ArrayStruct(x1, x2)
    
    print(x.first_array[0:9])
    >>> [1, 2, 3, 4, 5, 6, 7, 8, 9]
    

    到目前为止还不错:我已经创建了正确的类型,而且一切都正常工作。但接下来:

    myLib.print_array_struct(x)
    >>> 0.000000
    >>> 0.000000 
    >>> 0.000000
    >>> 0.000000
    >>> 0.000000
    >>> 0.000000
    >>> 0.000000
    >>> 0.000000
    >>> 0.000000
    >>> 0.000000
    

    我显然错过了什么。这个 ArrayStruct 类型被识别(否则调用 myLib.print_array_struct(x) 将引发错误),但未正确初始化。

    1 回复  |  直到 6 年前
        1
  •  1
  •   CristiFati    5 年前

    代码有两个问题(如我在评论中所说):

    • print_array_struct.argtype -哪个不正确
    • C 阵列是 双重的 基地,而在 蟒蛇 他们是 ctypes.c_int ( int )基于

    有关详细信息,请查看 [Python 3]: ctypes - A foreign function library for Python .
    我修改了你的 蟒蛇 代码,以纠正上述错误(以及其他一些小错误)。

    代码.py :

    #!/usr/bin/env python3
    
    import sys
    import ctypes
    
    
    DLL_NAME = "./my_so_object.so"
    
    DOUBLE_10 = ctypes.c_double * 10
    
    class ArrayStruct(ctypes.Structure):
        _fields_ = [
            ("first_array", DOUBLE_10),
            ("second_array", DOUBLE_10),
        ]
    
    
    def main():
        dll_handle = ctypes.CDLL(DLL_NAME)
        print_array_struct_func = dll_handle.print_array_struct
        print_array_struct_func.argtypes = [ArrayStruct]
        print_array_struct_func.restype = None
    
        x1 = DOUBLE_10()
        x2 = DOUBLE_10()
        x1[:] = range(1, 11)
        x2[:] = range(11, 21)
        print([item for item in x1])
        print([item for item in x2])
        arg = ArrayStruct(x1, x2)
        print_array_struct_func(arg)
    
    
    if __name__ == "__main__":
        print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
        main()
    

    产量 :

    [cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q050447199]> python3 code.py
    Python 3.5.2 (default, Nov 23 2017, 16:37:01)
    [GCC 5.4.0 20160609] on linux
    
    [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
    [11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0]
    1.000000
    2.000000
    3.000000
    4.000000
    5.000000
    6.000000
    7.000000
    8.000000
    9.000000
    10.000000