我正在尝试使用ctypes
的C库(libmms,尽管这并不重要);我首先编写了一个小型的C程序,但我似乎很难将它与ctypes
每当我使用test.restype = custom_t
指定返回类型(这是必需的,我以后需要它)时,事情就会开始中断。
我的论点(特定的url
)似乎不起作用,或者工作非常奇怪(参见C文件中的注释)。如果我将结构减少到只有一个条目(int a
),一切都按预期工作! (它在大约3或4行中断,libmms的原始结构更大)。
我(显然)尝试添加argtypes
,使用各种数据类型等等,都无济于事......
用于演示此问题的一些简单示例代码:
C库:
// Compiled with: clang -shared -Wl,-soname,test -o test.so -fPIC test.c
// Also tried gcc, with the same results
#include <stdio.h>
struct mmsh_t {
int a;
int b;
int c;
int d;
int e;
};
// Called as: test(None, None, b'Hello', 42)
// Outputs: mmsh_connect: (null)
struct mmsh_t *mmsh_connect (void *io, void *data, const char *url, int bandwidth) {
// Called as: test(42, b'Hello')
// Segfaults
// Curiously, when I output this with the Python code:
// test(b'Hello')
// It outputs: mmsh_connect: Hello
// Which is what I expected!
//struct mmsh_t *mmsh_connect (int io, const char *url) {
// Called as: test(b'Hello')
// Outputs: mmsh_connect:
//struct mmsh_t *mmsh_connect (const char *url) {
struct mmsh_t *this;
printf("mmsh_connect: %s\n", url);
return this;
}
Python代码:
#!/usr/bin/env python3
# Python2 give the same results
import ctypes
class custom_t(ctypes.Structure):
_fields_ = [
('a', ctypes.c_int),
('b', ctypes.c_int),
('c', ctypes.c_int),
('d', ctypes.c_int),
('e', ctypes.c_int),
]
lib = ctypes.cdll.LoadLibrary('./test.so');
test = lib.mmsh_connect
test.restype = custom_t # <- Oh woe is this line!
test(None, None, b'Hello', 42)
#test(42, b'Hello')
#test(b'Hello')
我错过了什么/做错了什么?
答案 0 :(得分:2)
该函数返回指向结构的指针,而不是结构。
test.restype = ctypes.POINTER(custom_t)
您还需要声明函数的参数:
lib.mmsh_connect.argtypes = [c_void_p, c_void_p, c_char_p, c_int]
用法:
s = lib.mmsh_connect(None, None, 'Hello', 42)
print ctypes.c_value(s.contents.a)