【问题标题】:How to return char** to ctypes with malloc如何使用 malloc 将 char** 返回到 ctypes
【发布时间】:2019-09-27 15:49:05
【问题描述】:

我一直在尝试通过 ctypes 将 char** 数组返回到我的 Python 代码中。我有一种“有效”的方法,但我不喜欢它,因为我必须在 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,以防万一。

【问题讨论】:

    标签: python c ctypes


    【解决方案1】:

    声明:

    names = (char**) malloc(sizeof(char*) * count);
    

    将内存分配给names,但 Python 中的调用者不会看到这一点。为此,请使用:

    *names = (char**) malloc(sizeof(char*) * count);
    

    这意味着您必须将函数声明为:

    int getStrings(char* fname, char ***names)
    

    三重间接。

    我不知道你需要在Python中改变什么,但至少你必须传递Pythonnames变量的地址。

    正确的 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;
    }
    

    【讨论】:

    • 我一直在努力解决这个问题,但这完全有道理。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2013-03-20
    • 2013-12-26
    • 2013-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-10
    • 1970-01-01
    相关资源
    最近更新 更多