2016-03-18 3 views
1

У меня есть объект PyUnicode, который я пытаюсь преобразовать обратно в строку C (char *).Как преобразование строк между строкой PyUnicode и строкой C?

То, как я пытаюсь это сделать, похоже, не работает. Вот мой код:

PyObject * objectCompName = PyTuple_GET_ITEM(compTuple, (Py_ssize_t) 0); 
PyObject * ooCompName = PyUnicode_AsASCIIString(objectCompName); 
char * compName = PyBytes_AsString(ooCompName); 
Py_DECREF(ooCompName); 

Есть ли другой/лучший способ, я должен это делать?

+0

Определить, что «похоже, не работает». Вы получаете аварии? Результаты отличаются от того, что вы хотели? В любом случае, что именно? –

+0

С какой версией Python вы работаете? –

+0

@JohnBollinger это segfaults, когда он попадает сюда. Python 3. – ComputerLocus

ответ

4

Если UTF-8 кодируются char * ОК, вы должны обязательно использовать PyUnicode_AsUTF8AndSize (который требует Python 3.3):

PyObject * objectCompName = PySequence_GetItem(compTuple, 0); 
if (! objectCompName) { 
    return NULL; 
} 

size_t size; 
char *ptr = PyUnicode_AsUTF8AndSize(objectCompName, &size); 
if (!ptr) { 
    return NULL; 
} 

// notice that the string pointed to by ptr is not guaranteed to stay forever, 
// and you need to copy it, perhaps by `strdup`. 

Также , поймите, что это обязательный, чтобы проверить возвращаемое значение каждого вызова Py*, который вы выполняете в своем коде.

Здесь PyTuple_GetItem вернется NULL если compTuple не tuple или 0 вызывает IndexError. PyUnicode_AsUTF8AndSize вернет NULL, если objectCompName не является объектом str. Игнорируйте возвращаемое значение, и CPython сработает с SIGSEGV, когда условия правильные.

+0

Строка PyUnicode изначально выполнена в другой функции C с использованием 'PyUnicode_DecodeASCII'. – ComputerLocus

+0

В этом случае 'PyUnicode_AsUTF8AndSize' очень хорошо. –

+0

Хорошо, отлично. Вы указываете, что «обязательно» проверять возвращаемые значения. Я планирую проверить их, я просто не был таким, каким хотел, просто проверить и убедиться, что он работает первым. Действительно ли это требование проверить возвращаемое значение, или вы просто говорите, что это очень хорошая практика? – ComputerLocus

0

Вам необходимо сначала преобразовать python PyUnicode в строку, не являющуюся unicode python (читайте больше здесь: https://docs.python.org/2/c-api/unicode.html#ascii-codecs), то вы можете легко преобразовать результат в char*.

Ниже приведен псевдокод, чтобы помочь вам продолжить:

// Assumption: you have a variable named "pyobj" which is 
// a pointer to an instance of PyUnicodeObject. 

PyObject* temp = PyUnicode_AsASCIIString(pyobj); 
if (NULL == temp) { 
    // Means the string can't be converted to ASCII, the codec failed 
    printf("Oh noes\n"); 
    return; 
} 

// Get the actual bytes as a C string 
char* c_str = PyByteArray_AsString(temp); 

// Use the string in some manner 
printf("The python unicode string is: %s\n", c_str); 

// Make sure the temp stuff gets cleaned up at the end 
Py_XDECREF(temp); 
+1

Строка с параметром 'PyByteArray_AsString (temp);' является segfault. – ComputerLocus

Смежные вопросы