2013-07-07 2 views
6

Я переношу много C++ с использованием API Python 2 (я не могу использовать такие вещи, как swig или boost.python по различным техническим причинам). Когда я должен передать строку (как правило, путь, всегда ASCII) в C/C++, я использовать что-то вроде этого:Чистый способ конвертировать Python 3 Unicode в std :: string

std::string file_name = PyString_AsString(py_file_name); 
if (PyErr_Occurred()) return NULL; 

Теперь я рассматриваю обновления для Python 3, где PyString_* методы не существует , Я нашел one solution, что говорит, что я должен сделать что-то вроде этого:

PyObject* bytes = PyUnicode_AsUTF8String(py_file_name); 
std::string file_name = PyBytes_AsString(bytes); 
if (PyErr_Occurred()) return NULL; 
Py_DECREF(bytes); 

Однако это в два раза больше строк и кажется немного некрасиво (не говоря уже о том, что он может ввести утечку памяти, если я забыл последнюю строку).

Другой вариант состоит в переопределении функции питона работать на bytes объектов и назвать их как этот

def some_function(path_name): 
    _some_function(path_name.encode('utf8')) 

Это не страшно, но это требует питон стороне обертки для каждой функции ,

Есть ли более чистый способ справиться с этим?

+0

Почему бы не 'std :: wstring'? –

+0

Хм, зачем мне использовать 'std :: wstring'? Я работаю исключительно с Linux, поэтому, насколько я понимаю, мне, вероятно, не нужна «wstring» для чего-либо. – Shep

+2

Почему бы просто не перевернуть его в свою собственную функцию, которая преобразует 'PyObject' в' std :: string'? 'std :: string convertPyString (PyObject * pyString);' –

ответ

1

Если вы знаете (и, конечно же, вы можете проверить с утверждают или аналогичный), что это все ASCII, то вы можете просто создать его так:

std::string py_string_to_std_string(PyUnicode_string py_file_name) 
{ 
    len = length of py_file_name;  // Not sure how you write that in python. 
    std::string str(len); 
    for(int i = 0; i < len; i++) 
     str += py_file_name[i]; 
    return str; 
} 
Смежные вопросы