【问题标题】:Python - ctypes - How to call functions and access struct fields?Python - ctypes - 如何调用函数和访问结构字段?
【发布时间】:2014-04-29 10:38:57
【问题描述】:

我有一个 C 库:

smart_string.h

typedef struct SmartString {
    unsigned string_len;
    unsigned alloc_len;
    char *str;
    char *str_terminator;

} SmartString;

SmartString *SmartString_new(char *str);
... definitions of more functions ...

该实现位于名为 smart_string.c 的文件中。

我需要一个指南来运行SmartString_new() 函数并访问返回的结构指针的字段。

谁能告诉我怎么做?

谢谢!

【问题讨论】:

    标签: python c++ c ctypes


    【解决方案1】:

    回答自己并与您分享知识:

    首先,需要从C文件创建一个共享库:

    gcc -shared -fpic smart_string.c -o SmartString.so

    然后,使用以下 Python 代码(有关每个已完成操作的说明,请参阅 cmets):

    注意char*,在上面的API中出现的是一个C可编辑字符串,而const char*是一个只读字符串。因为 C API 需要 char* 而不是 const char*,所以我们必须向它传递一个 mutable 字符串,以便它可以被 C 代码编辑。默认情况下,Python 字符串是不可变的。因此,我们在这里使用create_string_buffer() 函数

    python_smart_string.py

    import ctypes
    from ctypes import *
    
    # Defining the python type that represents the C SmartString
    # It must extend the 'Structure' class
    # Structure, c_uint, c_char_p, etc. were imported from ctypes
    class SmartString(Structure):
        _fields_=[("string_len",c_uint),
                  ("alloc_len",c_uint),
                  ("str",c_char_p),
                  ("str_terminator", c_char_p)]
    
    
    # Loading the C shared lib I've just compiled
    smartstring_lib = ctypes.CDLL('SmartString.so')
    
    # Defining pointer to the SmartString_new() function
    SmartString_new = smartstring_lib.SmartString_new
    
    # Declaring the function return type - a pointer to a SmartString object - just like in the C code
    SmartString_new.restype = POINTER(SmartString)
    
    # Declaring list of parameter types. In this case, the list contains only one item,
    # as the function has only one parameter
    SmartString_new.argtypes = [c_char_p]
    
    # Calling the SmartString_new() function. Expecting to get a pointer to SmartString object into 'my_str'
    # The API requires a MUTABLE string, so create_string_buffer() is used here
    # The reference to this string is not saved, as I don't care if it is modified by the C code
    my_str = SmartString_new(create_string_buffer('my nice string'))
    
    # Printing fields of the dereferenced returned value (dereferencing is done using '.contents')
    print my_str.contents.string_len
    print my_str.contents.alloc_len
    print my_str.contents.str
    print my_str.contents.str_terminator
    

    【讨论】:

    • 指定SmartString_new.argtypes = [c_char_p]。您可能需要保留对create_string_buffer() 的引用。 my_str[0] 是另一种取消引用指针的方法。
    猜你喜欢
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-24
    • 1970-01-01
    相关资源
    最近更新 更多