在python 2.7 ctypes中构建UCS4字符串缓冲区 [英] Building an UCS4 string buffer in python 2.7 ctypes
问题描述
试图重新创建 _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 $ c $可访问的任何其他类型的python, c>。
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屋!