Python C-API和Unicode字符串

问题描述:

我需要在python对象和各种编码的c字符串之间进行转换.使用PyUnicode_Decode从c字符串到unicode对象非常简单,但是我不确定如何反过来

I need to convert between python objects and c strings of various encodings. Going from a c string to a unicode object was fairly simple using PyUnicode_Decode, however Im not sure how to go the other way

//char* can be a wchar_t or any other element size, just make sure it is correctly terminated for its encoding
Unicode(const char *str, size_t bytes, const char *encoding="utf-16", const char *errors="strict")
    :Object(PyUnicode_Decode(str, bytes, encoding, errors))
{
    //check for any python exceptions
    ExceptionCheck();
}

我想创建另一个函数,该函数采用python Unicode字符串,并使用给定的编码将其放入缓冲区,例如:

I want to create another function that takes the python Unicode string and puts it in a buffer using a given encodeing, eg:

//fills buffer with a null terminated string in encoding
void AsCString(char *buffer, size_t bufferBytes,
    const char *encoding="utf-16", const char *errors="strict")
{
    ...
}

我怀疑它与PyUnicode_AsEncodedString有关,但是返回了PyObject,所以我不确定如何将其放入缓冲区...

I suspect it has somthing to do with PyUnicode_AsEncodedString however that returns a PyObject so I'm not sure how to put that into my buffer...

注意:上面的两个方法都是包装python api的c ++ Unicode类的成员 我正在使用Python 3.0

Note: both methods above are members of a c++ Unicode class that wraps the python api I'm using Python 3.0

我怀疑它与PyUnicode_AsEncodedString有关,但是返回了PyObject,所以我不确定如何将其放入缓冲区...

I suspect it has somthing to do with PyUnicode_AsEncodedString however that returns a PyObject so I'm not sure how to put that into my buffer...

返回的PyObject是一个PyStringObject,因此您只需要使用PyString_SizePyString_AsString来获取指向字符串缓冲区的指针,并将其指向您自己的缓冲区.

The PyObject returned is a PyStringObject, so you just need to use PyString_Size and PyString_AsString to get a pointer to the string's buffer and memcpy it to your own buffer.

如果您正在寻找直接从PyUnicode对象 进入自己的char缓冲区的方法,我认为您无法做到这一点.

If you're looking for a way to go directly from a PyUnicode object into your own char buffer, I don't think that you can do that.