如何使用 malloc return char** 到 ctypes
How to return char** to ctypes with malloc
我一直在尝试通过 ctypes return 一个 char** 数组到我的 Python 代码中。我有一个 "works" 的方法,但我不喜欢它,因为我必须在 Python 端有一些额外的代码。我不得不相信这是可能的。
我的Python代码:
from ctypes import *
strarray = POINTER(c_char_p)
getStr = cdll.context.getStrings
getStr.argtypes = [c_char_p, strarray]
fname = b"test.ctx"
names = strarray()
int numStrs = getStr(fname, names)
for i in range(numStrs):
print(names[i])
我的C/C++代码:
int getStrings(char* fname, char **names)
{
int count;
int strSize;
count = getNameCount();
names = (char**) malloc(sizeof(char*) * count);
for (int i = 0; i < count; i++)
{
std::string name = getName(i);
strsize = name.length() + 1;
*names = (char*) malloc(strsize *sizeof(char));
strcpy_s(*parts, strsize, name.c_str());
*names++;
}
return count;
}
当我尝试打印 Python 中的 names
时,我得到 ValueError: NULL pointer access
.
正如我所说,我有类似的作品。在 Python 中,如果我不使用 POINTER(c_char_p)
而是指定一些指针,例如 c_char_p*4096
并从 C 代码中删除 malloc
,我可以得到结果美好的。不过,理想情况下,我想在 C 端分配内存。我觉得我缺少一些微妙之处。
我正在使用 Python 3.5.2,以防万一。
声明:
names = (char**) malloc(sizeof(char*) * count);
将内存分配给 names
但 Python 中的调用者将看不到它。为此,请使用:
*names = (char**) malloc(sizeof(char*) * count);
这意味着您必须将函数声明为:
int getStrings(char* fname, char ***names)
三重间接寻址。
我不知道你在Python中需要改变什么,但至少你必须传递Python names
变量的地址。
正确的 C (C++) 代码是:
int getStrings(char* fname, char ***names)
{
int count;
int strSize;
count = getNameCount();
*names = (char**) malloc(sizeof(char*) * count);
for (int i = 0; i < count; i++)
{
std::string name = getName(i);
strsize = name.length() + 1;
(*names)[i] = (char*) malloc(strsize *sizeof(char));
strcpy_s((*names)[i], strsize, name.c_str());
}
return count;
}
我一直在尝试通过 ctypes return 一个 char** 数组到我的 Python 代码中。我有一个 "works" 的方法,但我不喜欢它,因为我必须在 Python 端有一些额外的代码。我不得不相信这是可能的。
我的Python代码:
from ctypes import *
strarray = POINTER(c_char_p)
getStr = cdll.context.getStrings
getStr.argtypes = [c_char_p, strarray]
fname = b"test.ctx"
names = strarray()
int numStrs = getStr(fname, names)
for i in range(numStrs):
print(names[i])
我的C/C++代码:
int getStrings(char* fname, char **names)
{
int count;
int strSize;
count = getNameCount();
names = (char**) malloc(sizeof(char*) * count);
for (int i = 0; i < count; i++)
{
std::string name = getName(i);
strsize = name.length() + 1;
*names = (char*) malloc(strsize *sizeof(char));
strcpy_s(*parts, strsize, name.c_str());
*names++;
}
return count;
}
当我尝试打印 Python 中的 names
时,我得到 ValueError: NULL pointer access
.
正如我所说,我有类似的作品。在 Python 中,如果我不使用 POINTER(c_char_p)
而是指定一些指针,例如 c_char_p*4096
并从 C 代码中删除 malloc
,我可以得到结果美好的。不过,理想情况下,我想在 C 端分配内存。我觉得我缺少一些微妙之处。
我正在使用 Python 3.5.2,以防万一。
声明:
names = (char**) malloc(sizeof(char*) * count);
将内存分配给 names
但 Python 中的调用者将看不到它。为此,请使用:
*names = (char**) malloc(sizeof(char*) * count);
这意味着您必须将函数声明为:
int getStrings(char* fname, char ***names)
三重间接寻址。
我不知道你在Python中需要改变什么,但至少你必须传递Python names
变量的地址。
正确的 C (C++) 代码是:
int getStrings(char* fname, char ***names)
{
int count;
int strSize;
count = getNameCount();
*names = (char**) malloc(sizeof(char*) * count);
for (int i = 0; i < count; i++)
{
std::string name = getName(i);
strsize = name.length() + 1;
(*names)[i] = (char*) malloc(strsize *sizeof(char));
strcpy_s((*names)[i], strsize, name.c_str());
}
return count;
}