Python - ctypes - 如何调用函数和访问结构字段?

Posted

技术标签:

【中文标题】Python - ctypes - 如何调用函数和访问结构字段?【英文标题】:Python - ctypes - How to call functions and access struct fields? 【发布时间】: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() 函数并访问返回的结构指针的字段。

谁能告诉我怎么做?

谢谢!

【问题讨论】:

【参考方案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] 是另一种取消引用指针的方法。

以上是关于Python - ctypes - 如何调用函数和访问结构字段?的主要内容,如果未能解决你的问题,请参考以下文章

Python 外部函数调用库ctypes简介

python--ctypes模块:调用C函数

如何使用 ctypes 调用具有双下划线函数名的 DLL 函数?

使用 Python 的 ctypes 调用涉及自定义类型的函数

python使用ctypes调用C编译dll函数方法

求助python调用dll函数里,关于数据指针和长度应该如何获得呢?