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

Python-ctypes-如何调用函数和访问结构字段?,python,c++,c,ctypes,Python,C++,C,Ctypes,我有一个C库: 智能字符串.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 ... import ctypes fro

我有一个C库:

智能字符串.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 ...
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
在名为smart_string.c的文件中可以找到该实现

我需要一个运行
SmartString\u new()
函数和访问返回的结构指针字段的指南

谁能告诉我怎么做吗


谢谢

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

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

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

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

注意
char*
,如上面的API所示,是一个C可编辑字符串,而
const char*
是一个只读字符串。因为C API需要
char*
而不是
const char*
,所以我们必须向它传递一个可变的字符串,这样它就可以被C代码编辑。默认情况下,Python字符串是不可变的。因此,我们在这里使用
create\u string\u buffer()
函数

python\u smart\u string.py

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

} SmartString;

SmartString *SmartString_new(char *str);
... definitions of more functions ...
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\u new.argtypes=[c\u char\u p]
。您可能需要保留对
create\u string\u buffer()
的引用
my_str[0]
是解除指针引用的另一种方法。