正如David Schwartz指出的那样,如果将restype设置为c_char_p
,则ctypes将返回常规的Python字符串对象。解决此问题的一种简单方法是使用avoid *
并强制转换结果:
string.c:
#include <stdlib.h>
#include <string.h>
#include <st@R_404_2369@.h>
char *get(void)
{
char *buf = "Hello World";
char *new_buf = strdup(buf);
printf("allocated address: %p\n", new_buf);
return new_buf;
}
void freeme(char *ptr)
{
printf("freeing address: %p\n", ptr);
free(ptr);
}
Python用法:
from ctypes import *
lib = cdll.LoadLibrary('./string.so')
lib.freeme.argtypes = c_void_p,
lib.freeme.restype = None
lib.get.argtypes = []
lib.get.restype = c_void_p
>>> ptr = lib.get()
allocated address: 0x9facad8
>>> hex(ptr)
'0x9facad8'
>>> cast(ptr, c_char_p).value
'Hello World'
>>> lib.freeme(ptr)
freeing address: 0x9facad8
您还可以使用的子类c_char_p
。事实证明,ctypes不会getfunc
为简单类型的子类调用。
class c_char_p_sub(c_char_p):
pass
lib.get.restype = c_char_p_sub
该value
属性返回字符串。您可以将参数保留freeme
为更通用c_void_p
。那可以接受任何指针类型或整数地址。