Python ctypes.string_在释放行为时

Python ctypes.string_在释放行为时,python,memory-management,ctypes,Python,Memory Management,Ctypes,我正在使用ctypes将一些C函数从DLL公开到Python脚本。其中一个函数返回一个动态大小的字符数组,我希望能够在Python中读取该数组的内容,但也希望在使用完该数组后释放该数组的内存 示例C代码: ... #ifdef __cplusplus extern "C" { #endif __declspec(dllexport) char * WINAPI get_str() { int str_len = ... // figure out how lon

我正在使用ctypes将一些C函数从DLL公开到Python脚本。其中一个函数返回一个动态大小的字符数组,我希望能够在Python中读取该数组的内容,但也希望在使用完该数组后释放该数组的内存

示例C代码:

...

#ifdef __cplusplus
extern "C"
{
#endif
    __declspec(dllexport) char * WINAPI get_str()
    {
        int str_len = ... // figure out how long it is gonna be and set it here
        char *ary = (char *)malloc(sizeof(char) * str_len);

        // populate the array
        ...

        ary[str_len - 1] = '\0';

        return ary;
    }

#ifdef __cplusplus
}
#endif
我构建我的DLL,将其复制到可以找到的位置,然后生成以下Python代码:

import ctypes

my_dll = ctypes.WinDLL("MyDLLName.dll")

some_str = ctypes.string_at(my_dll.get_str())

print some_str

这段代码都能正常工作。我的问题是:因为ctypes.string_at在指定的内存位置创建了一个字符串,当一些字符串超出Python解释器的作用域时,该内存将被垃圾收集,还是需要手动释放?

string_at
在新的内存位置创建一个新的Python字符串,完全独立于调用它的内存位置

Python或ctypes无法猜测您的本机代码返回了什么-就它而言,它只是一个数字(在本例中它恰好是一个有效指针)

因此,经验法则是:如果您编写分配内存的C代码,您还应该编写等效的C代码来取消分配内存,并使用Python代码将C代码从CType中释放出来

对于像这样的快速脚本和示例,因为您知道它是一个简单的分配字符串,所以可以通过使用ctypes调用system
free
函数直接从Python端释放它

也就是说,将返回的指针存储在Python变量中: (您可以将其cat设置为正确的ctypes指针类型,也可以不设置为正确的ctypes指针类型),并且在, 使用:


我可能已经回答了我自己的问题。。。我编写了一个无限循环,让它在反复调用我的_dll.get_str()时运行,并在Windows中观察我的内存使用情况,它似乎在继续攀升。尽管如此,为了理智起见,我还是希望得到一个具体的答案。谢谢!我也这么想;我只是想确定一下。您是否检查过C字符串中创建的地址与Python指针的地址完全相同?我有同样的问题,我发现他们是不同的。
pointer = my_dll.get_str()
some_str = ctypes.string_at(pointer)
# This is windows specific - 
# on Posix, one have to load "libc.so" and use "free" from there:
ctypes.cdll.msvcrt.free(pointer)