Python CTYPE:如何释放内存?获取无效的指针错误
我想从带有ctypes的C / C ++库中获取一些字符串到python中。我的代码如下所示:
lib中的代码:
const char* get(struct something *x)
{
[...]
// buf is a stringstream
return strdup(buf.str().c_str());
}
void freeme(char *ptr)
{
free(ptr);
}
Python代码:
fillprototype(lib.get, c_char_p, POINTER(some_model)])
fillprototype(lib.freeme, None, [c_char_p])
// what i want to do here: get a string into python so that i can work
// with it and release the memory in the lib.
c_str = lib.get(some_model)
y = ''.join(c_str)
lib.freeme(c_str)
如果我print()c_str,一切都在那里。问题是(或似乎是)在最后一行Python中。我无法释放内存-
库得到了错误的指针。我在这里做错了什么?(并且请不要建议boost :: python左右)。
*** glibc detected *** python2: munmap_chunk(): invalid pointer: 0x00000000026443fc ***
-
正如David Schwartz指出的那样,如果将restype设置为
c_char_p
,则ctypes将返回常规的Python字符串对象。解决此问题的一种简单方法是使用avoid *
并强制转换结果:string.c:
#include <stdlib.h> #include <string.h> #include <stdio.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
。那可以接受任何指针类型或整数地址。