2010-09-19 2 views
6

Я работаю с существующим модулем на данный момент, который предоставляет интерфейс C++ и выполняет несколько операций со строками.Python: передача строки Unicode в C++-модуль

мне нужно использовать строки Unicode и модуль, к сожалению, не было никакой поддержки интерфейса Unicode, поэтому я написал дополнительную функцию, чтобы добавить к интерфейсу:

void SomeUnicodeFunction(const wchar_t* string) 

Однако, когда я пытаюсь используйте следующий код в Python:

SomeModule.SomeUnicodeFunction(ctypes.c_wchar_p(unicode_string)) 

Я получаю эту ошибку:

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

(имена изменены).

Я пробовал сменить wchar_t в модуле C++ на Py_UNICODE без успеха. Как решить эту проблему?

+0

Boost.python автоматически не распознает типы ctypes, насколько мне известно, но, вероятно, он должен работать со встроенными строками unicode. Что произойдет, если вы попытаетесь вызвать 'SomeModule.SomeUnicodeFunction (unicode_string)'? – Doug

+0

@ Достаточно: та же ошибка, но с «unicode» вместо «c_wchar_p» в качестве типа аргумента Python. –

+0

@Matthew, без/c 'c_wchar_p', похоже, что он работает _should_, за исключением, возможно, для' const' (который нигде не упоминается в документах 'ctypes') - что произойдет, если вы опустите' const в коде C? (Обратите внимание: нет прямой поддержки C++ в 'ctypes': функция должна быть' extern C' с точки зрения C++, конечно). –

ответ

2

Для Linux вам не нужно менять свой API, просто сделать:

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

В Windows все Unicode API, используют UTF-16 LE (Little Endian), поэтому вы должны кодировать так:

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

Хорошо знать: wchar_t может иметь различные размеры на разных платформах: 8, 16 или 32 бит.

+0

Я использую Linux, на самом деле. Я обновил свой собственный ответ на вопрос. –

2

Найдено хак для работы вокруг проблемы:

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

Это, кажется, работает хорошо для моих целей до сих пор.

Обновление: Фактически, использование UTF-8 означает, что я не нуждаюсь в SomeUnicodeFunction и могу использовать стандартную функцию SomeFunction, не специализируясь на Unicode. Узнай что-то новое каждый день, я думаю :).

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