2010-09-19 12 views
6

Attualmente sto lavorando con un modulo esistente che fornisce un'interfaccia C++ e fa alcune operazioni con le stringhe.Python: passaggio della stringa unicode al modulo C++

ho bisogno di usare le stringhe Unicode e il modulo, purtroppo, non ha avuto alcun supporto per l'interfaccia Unicode, così ho scritto una funzione in più per aggiungere l'interfaccia:

void SomeUnicodeFunction(const wchar_t* string) 

Tuttavia, quando tento di utilizzare il seguente codice in Python:

SomeModule.SomeUnicodeFunction(ctypes.c_wchar_p(unicode_string)) 

ottengo questo errore:

ArgumentError: Python argument types in 
    SomeModule.SomeUnicodeFunction(SomeModule, c_wchar_p) 
did not match C++ signature: 
    SomeUnicodeFunction(... {lvalue}, wchar_t const*) 

(i nomi sono stati modificati).

Ho provato a cambiare wchar_t nel modulo C++ a Py_UNICODE senza successo. Come risolvo questo problema?

+0

Boost.python non riconosce automaticamente i tipi di caratteri, per quanto ne so, ma probabilmente dovrebbe funzionare solo con stringhe unicode incorporate. Cosa succede se provi a chiamare 'SomeModule.SomeUnicodeFunction (unicode_string)'? – Doug

+0

@Dough: lo stesso errore, ma con "unicode" invece di "c_wchar_p" come tipo di argomento Python. –

+0

@Matthew, w/o w/o il cast di 'c_wchar_p', sembra che _should_ funzioni eccetto forse per il' const' (che non è menzionato da nessuna parte nei documenti 'ctypes'') - cosa succede se si omette il ' const' nel codice C? (Nota: non esiste un supporto C++ diretto in 'ctypes': la funzione deve essere' extern C' dal punto di vista di un C++, ovviamente). –

risposta

2

Per Linux non devi cambiare il tuo API, basta fare:

SomeModule.SomeFunction(str(s.encode('utf-8'))) 

In Windows tutte le API Unicode utilizzano UTF-16 LE (Little Endian) in modo da avere per codificare in questo modo:

SomeModule.SomeFunctionW(str(s.encode('utf-16-le'))) 

buono a sapersi: wchar_t può avere diverse dimensioni su diverse piattaforme: 8, 16 o 32 bit.

+0

Sto usando Linux, in realtà. Ho aggiornato la mia risposta alla domanda. –

2

Trovato un trucco per aggirare il problema:

SomeModule.SomeUnicodeFunction(str(s.encode('utf-8'))) 

Sembra funzionare bene per i miei scopi finora.

Aggiornamento: in realtà, l'utilizzo di UTF-8 significa che evito qualsiasi necessità di SomeUnicodeFunction e posso utilizzare la funzione SomeFunction standard senza specializzazione per Unicode. Impara qualcosa di nuovo ogni giorno immagino :).

Problemi correlati