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';
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
.
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).
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):
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.