不要将 pBuf 声明为c_char_p
. ctypes
将该类型转换为不可变的 Python 字符串,您将无法访问 C 指针地址。您需要将其声明为POINTER(c_char)
,然后可以使用ctypes.memmove
将数据复制到其中。窗口示例:
DLL 代码(在 MSVC 上编译为cl /LD test.c
)
#ifdef _WIN32
# define API __declspec(dllexport)
#else
# define API
#endif
typedef int (*CALLBACK)(void *pFileHandle, char *pBuf, long nBufLength);
char g_buf[10] = "012345678";
CALLBACK g_callback;
API void set_callback(CALLBACK callback) {
g_callback = callback;
}
API int call_callback() {
return g_callback(0, g_buf, 10);
}
API const char* get_buf() {
return g_buf;
}
Python 3 代码:
import ctypes as ct
# Declare the callback type, argument types and return types
CALLBACK = ct.CFUNCTYPE(ct.c_int,ct.c_void_p,ct.POINTER(ct.c_char),ct.c_long)
dll = ct.CDLL('./test')
dll.set_callback.argtypes = CALLBACK,
dll.set_callback.restype = None
dll.call_callback.argtypes = ()
dll.call_callback.restype = ct.c_int
dll.get_buf.argtypes = ()
dll.get_buf.restype = ct.c_char_p
# Decorating a Python function as a callback
# makes it usable as a ctypes parameter.
@CALLBACK
def callback(handle, buf, length):
data = b'ABCD\0'
if length < len(data):
return 0
ct.memmove(buf,data,len(data))
return 1
dll.set_callback(callback)
print(dll.call_callback())
print(dll.get_buf())
输出。请注意,它get_buf
返回 ac_char_p
并且它是一个字节字符串。const char*
价值丢失。
1
b'ABCD'