2013-07-07 15 views
6

Ho avvolto un sacco di C++ usando l'API Python 2 (non posso usare cose come swig o boost.python per vari motivi tecnici). Quando devo passare una stringa (di solito un percorso, sempre ASCII) in C/C++, utilizzare qualcosa di simile:Modo pulito per convertire Python 3 Unicode in std :: string

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

Ora sto considerando l'aggiornamento a Python 3, dove non esistono metodi PyString_* . Ho trovato one solution che dice che dovrei fare qualcosa di simile:

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

Tuttavia questo è il doppio delle linee e sembra un po 'brutto (per non parlare che si potrebbe introdurre una perdita di memoria se dimentico l'ultima riga).

L'altra opzione è ridefinire le funzioni pitone per operare su bytes oggetti, e chiamarli simili

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

Questo non è terribile, ma richiede un involucro pitone lato per ogni funzione .

C'è un modo più pulito per affrontare questo?

+0

Perché non 'std :: wstring'? –

+0

Hmm, perché dovrei usare 'std: wstring'? Sto lavorando esclusivamente con Linux, quindi, a quanto ho capito, probabilmente non ho bisogno di un 'wstring' per niente. – Shep

+2

Perché non limitarsi a racchiuderlo nella propria funzione nativa che converte 'PyObject' in' std :: string'? 'std :: string convertPyString (PyObject * pyString);' –

risposta

1

Se si conosce (e, naturalmente, si potrebbe verificare con un'asserzione o simile) che è tutto ASCII, allora si potrebbe semplicemente creare in questo modo:

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; 
} 
Problemi correlati