snø*_*ven 16 c c++ python ctypes
我想从带有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);
}
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
如果我打印()c_str,一切都在那里.问题是(或似乎是)在最后一个Python行中.我无法释放内存 - 库得到错误的指针.我在这做错了什么?(请不要建议使用boost :: python等).
*** glibc detected *** python2: munmap_chunk(): invalid pointer: 0x00000000026443fc ***
Run Code Online (Sandbox Code Playgroud)
Ery*_*Sun 26
正如David Schwartz指出的那样,如果将restype设置为c_char_p,则ctypes会返回一个常规的Python字符串对象.解决这个问题的一个简单方法是使用a void *并转换结果:
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);
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
您还可以使用的子类c_char_p.事实证明,ctypes不会调用getfuncfor类的简单类型.
class c_char_p_sub(c_char_p):
pass
lib.get.restype = c_char_p_sub
Run Code Online (Sandbox Code Playgroud)
该value属性返回字符串.您可以将参数保留freeme为更通用的参数c_void_p.它接受任何指针类型或整数地址.
| 归档时间: |
|
| 查看次数: |
8831 次 |
| 最近记录: |