Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Python ctypes:如何释放内存?获取无效指针错误_C++_Python_C_Ctypes - Fatal编程技术网

C++ Python ctypes:如何释放内存?获取无效指针错误

C++ Python ctypes:如何释放内存?获取无效指针错误,c++,python,c,ctypes,C++,Python,C,Ctypes,我想从C/C++库中获取一些字符串,将ctypes转换成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

我想从C/C++库中获取一些字符串,将ctypes转换成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) 
如果我打印()c_str,一切都在那里。问题在(或似乎在)最后一行Python中。我无法释放内存-库的指针出错。我做错了什么?(请不要建议boost::python之类的东西)


正如David Schwartz指出的,如果将restype设置为
c\u char\u p
,那么ctypes将返回一个常规的Python字符串对象。解决此问题的一个简单方法是使用
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);
}

您还可以使用
c\u char\p
的子类。事实证明,对于简单类型的子类,ctypes不会调用
getfunc

class c_char_p_sub(c_char_p):
    pass

lib.get.restype = c_char_p_sub

value
属性返回字符串。您可以将
freeme
的参数保留为更通用的
c\u void\p
。它可以接受任何指针类型或整数地址。

释放内存的一种廉价方法是在C中静态分配内存,而从不释放内存。当然,只有当你知道你需要的最大量,并且在第二次调用你的例程之前你知道你已经完成了,它才会起作用

static char _externalStringBuffer[MAX_BUFFER_SIZE];
char *get() {
    // put characters in _externalStringBuffer
    return _externalStringBuffer;
}

为什么
get
返回一个
const char*
但是
freeme
expect
char*
?你希望你的来电者放弃常数吗?很好。。不幸的是,这并没有解决问题。这是32位还是64位代码?您知道错误发生在哪一行代码中吗?它不一定是
免费(ptr)
.64位。我不知道它是哪一行:gdb bt只向我展示了很多python的东西。但是我只是在GET()中和在Frimee()中打印了PTR,得到了:“分配内存PTR:0x2592A20”、“空闲内存PTR:0x7F2BF5FAD3FC”、“Python 2: MunMaMax Cyk():无效指针:0x000、72f2bf5fAD3FC。”我打赌Python创建了自己的字符串,就像C++一样,如果你做了代码>字符串CySTR=LIB。代码>。我必须在释放时强制转换指针,例如:
lib.freeme(cast(ptr,c_char_p))
,否则我会在python3中遇到此错误:
ctypes.ArgumentError:Argument1::错误的类型
。这是一个非常糟糕的建议,因为多次调用该函数将更改现在的全局变量。True。。这就是为什么我加入了“只有在……你知道在第二次调用你的例程之前你已经完成了(它)”的情况下才有效。
class c_char_p_sub(c_char_p):
    pass

lib.get.restype = c_char_p_sub
static char _externalStringBuffer[MAX_BUFFER_SIZE];
char *get() {
    // put characters in _externalStringBuffer
    return _externalStringBuffer;
}