2010-09-19 10 views
6

Pracuję z istniejącym modułem w momencie, który zapewnia interfejs C++ i wykonuje kilka operacji z ciągami.Python: Przekazywanie łańcucha Unicode do modułu C++

Musiałem użyć ciągi Unicode i moduł niestety nie osamotniony dla interfejsu Unicode, więc napisałem dodatkową funkcję dodawania do interfejsu:

void SomeUnicodeFunction(const wchar_t* string) 

jednak, gdy próbuję należy użyć następującego kodu w Pythonie:

SomeModule.SomeUnicodeFunction(ctypes.c_wchar_p(unicode_string)) 

otrzymuję ten błąd:

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

(nazwy zostały zmienione).

Próbowałem zmienić wchar_t w module C++ na Py_UNICODE bez powodzenia. Jak rozwiązać ten problem?

+0

Boost.python nie rozpoznaje automatycznie typów ctypes, o ile wiem, ale prawdopodobnie powinien po prostu działać z wbudowanymi ciągami Unicode. Co się stanie, jeśli spróbujesz wywołać 'SomeModule.SomeUnicodeFunction (unicode_string)'? – Doug

+0

@Dough: ten sam błąd, ale z "unicode" zamiast "c_wchar_p" jako typem argumentu Python. –

+0

@Matthew, w/lub bez rzutowania 'c_wchar_p', wygląda na to, że powinien" pracować "z wyjątkiem może dla' const' (które nigdzie nie jest wspomniane w dokumentach 'ctypes') - co się stanie, jeśli pominiesz' const' w kodzie C? (Zauważ, że nie ma bezpośredniej obsługi C++ w 'ctypes': funkcja musi oczywiście mieć postać' extern C' z punktu widzenia C++ '). –

Odpowiedz

2

Dla Linuksa nie trzeba zmienić API, po prostu zrobić:

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

W systemie Windows wszystkie funkcje API Unicode są przy użyciu UTF-16 LE (Little Endian) więc trzeba zakodować to w ten sposób:

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

Dobrze wiedzieć: wchar_t mogą mieć różne rozmiary na różnych platformach: 8, 16 lub 32 bitów.

+0

Używam Linuksa. Zaktualizowałem własną odpowiedź na to pytanie. –

2

Znaleziony hack aby obejść problem:

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

Wydaje się, że działa dobrze dla moich celów tej pory.

Aktualizacja: W rzeczywistości, używając UTF-8, unikam potrzeby użycia SomeUnicodeFunction i mogę używać standardowego SomeFunction bez specjalizacji w Unicode. Naucz się czegoś nowego każdego dnia :).

Powiązane problemy