在python 2.7 ctypes中构建UCS4字符串缓冲区 [英] Building an UCS4 string buffer in python 2.7 ctypes

查看:109
本文介绍了在python 2.7 ctypes中构建UCS4字符串缓冲区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

试图重新创建 _winapi.c getenvironment(..) C函数(直接链接)在纯python中使用 ctypes 我想知道如何翻译以下C代码

In an attempt to recreate the getenvironment(..) C function of _winapi.c (direct link) in plain python using ctypes, I'm wondering how the following C code could be translated:

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(..) doc 代码)正在做的很接近,我可以重现如果只有我可以访问 Py_UCS4 C类型,或者确保它链接到通过 ctypes

It seems that the function ctypes.create_unicode_buffer(..) (doc, code) is doing something quite close that I could reproduce if only I could have an access to Py_UCS4 C type or be sure of its link to any other type accessible to python through ctypes.

c_wchar 会是一个很好的候选人吗?但看来我无法做出这样的假设,因为如果我正确的话,Python 2.7可以在 UCS-2 中进行编译(源代码),我想Windows真的在等待 UCS-4 ……即使看起来 ctypes.wintypes.LPWSTR c_wchart_p (代码)。

Would c_wchar be a good candidate ?, but it seems I can't make that assumption, as python 2.7 could be compiled in UCS-2 if I'm right (source), and I guess windows is really waiting fo UCS-4 there... even if it seems that ctypes.wintypes.LPWSTR is an alias to c_wchart_p in cPython 2.7 (code).

对于这个问题,可以假设目标平台是Windows上的python 2.7(如果有帮助)。

For this question, it is safe to make the assumption that the target platform is python 2.7 on Windows if that helps.

上下文(如果有重要意义):

Context (if it has some importance):

我正在研究第一个在 ctypes 中尝试对cPython 2.7的bug进行普通的python修复,击中Windows subprocess.Popen(..)实施。 此错误无法修复。此错误阻止在命令行调用中使用unicode(作为可执行文件名称或自变量)。这在python 3中已修复,所以我要在纯Python中反向实现所需的 CreateProcess(..)中的实际cPython3实现。 c> _winapi.c 依次调用 getenvironment(..)
在与相关的问题的此答案的注释中提到了这种可能的解决方法。 subprocess.Popen(..) unicode问题。

I'm in the process of delving for the first time in ctypes to attempt a plain python fix at cPython 2.7's bug hitting windows subprocess.Popen(..) implementation. This bug is a won't fix. This bug prevents the usage of unicode in command line calls (as executable name or arguments). This is fixed in python 3, so I'm having a go at reverse implementing in plain python the actual cPython3 implementation of the required CreateProcess(..) in _winapi.c which calls in turn getenvironment(..). This possible workaround was mentionned in the comments of this answer to a question related to subprocess.Popen(..) unicode issues.

推荐答案

关于构建的标题,特别是 UCS4 缓冲区。但是它以粗体部分回答了这个问题,并设法创建了一个unicode缓冲区,该缓冲区似乎可以在Windows上的当前python 2.7上运行:(所以也许不需要UCS4)。

This doesn't answer the part in the title about build specifically UCS4 buffer. But it gives a partial answer to the question in bold and manage to create a unicode buffer that seems to work on my current python 2.7 on windows: (so maybe UCS4 is not required).

所以我们在这里假设 c_wchar 是Windows所需的(对我来说还不是很清楚,如果是UCS4或UCS2,它可能没有重要性,但我想对自己的知识抱有非常轻的信心。)

So we are here taking the assumption that c_wchar is what windows require (if it is UCS4 or UCS2 is not so clear to me yet, and it might have no importance, but I recon having a very light confidence in my knowledge here).

因此,这是可按问题要求复制C代码的python代码:

So here is the python code that reproduces the C code as requested in the question:

## 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 ,这似乎可行。

This wenv can then be fed to CreateProcessW and this seems to work.

这篇关于在python 2.7 ctypes中构建UCS4字符串缓冲区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆