在python 2.7 ctypes中构建UCS4字符串缓冲区

时间:2017-03-14 08:20:20

标签: windows python-2.7 unicode ctypes

尝试使用getenvironment(..)在普通python中重新创建_winapi.cdirect link)的ctypes C函数,我想知道如何以下C代码可以翻译

buffer = PyMem_NEW(Py_UCS4, totalsize);
if (! buffer) {
    PyErr_NoMemory();
    goto error;
}
p = buffer;
end = buffer + totalsize;

for (i = 0; i < envsize; i++) {
    PyObject* key = PyList_GET_ITEM(keys, i);
    PyObject* value = PyList_GET_ITEM(values, i);
    if (!PyUnicode_AsUCS4(key, p, end - p, 0))
        goto error;
    p += PyUnicode_GET_LENGTH(key);
    *p++ = '=';
    if (!PyUnicode_AsUCS4(value, p, end - p, 0))
        goto error;
    p += PyUnicode_GET_LENGTH(value);
    *p++ = '\0';
}

/* add trailing null byte */
*p++ = '\0';

似乎函数ctypes.create_unicode_buffer(..)doccode)正在做一些非常接近的事情,如果只有我可以访问Py_UCS4 C类型的话我可以重现或确保通过ctypes链接到python可访问的任何其他类型。

c_wchar会成为一个好的候选人吗?但似乎我无法做出这样的假设,因为如果我正确的话,可以在UCS-2编译python 2.7({{ 3}}),我猜Windows正在等待UCS-4 ......即使ctypes.wintypes.LPWSTR似乎是cPython 2.7中c_wchart_p的别名(source )。

对于这个问题,可以安全地假设目标平台在Windows上是python 2.7,如果有帮助的话。

上下文(如果它有一些重要性):

我正在ctypes中第一次尝试在cPython 2.7中尝试一个普通的python修复程序来实现Windows subprocess.Popen(..)code。此错误可防止在命令行调用中使用unicode(作为可执行文件名或参数)。这是在python 3中修复的,所以我在普通的python中反向实现CreateProcess(..)_winapi.c所需的getenvironment(..)的实际cPython3实现,它依次调用subprocess.Popen(..)This bug is a won't fixDictionary<String, Double> unicode问题相关问题的评论中提到了这种可行的解决方法。

1 个答案:

答案 0 :(得分:0)

这不会回答标题中有关专门构建UCS4缓冲区的部分。但它以粗体显示部分答案并设法创建一个unicode缓冲区,似乎可以在我当前的Windows上运行python 2.7 :(因此可能不需要UCS4)。

所以我们在这里假设c_wchar是Windows需要的(如果它是UCS4或UCS2对我来说还不是那么清楚,而且它可能没有重要性,但我重新拥有非常轻松的信心据我所知)。

所以这里是python代码,它按照问题中的要求再现C代码:

## creation of buffer of size totalsize
wenv = (c_wchar * totalsize)()    
wenv.value = (unicode("").join([
    unicode("%s=%s\0") % (key, value)
    for k, v in env.items()])) + "\0"

然后可以将此wenv提供给CreateProcessW,这似乎有效。