Передача UTF-8 строки из Python в С++ DLL

81
06 января 2021, 14:30

Пытаюсь передать строку UTF-8 (кириллица) из Python на вход с++ DLL

Код на Python:

from ctypes import *
import os
nDLL = CDLL('LingProcDll.dll')
ffff = open('D:\\1\\test.txt')
ffff1=str(ffff.read())
b_ffff=ffff1.encode('utf-8')
nDLL.LP_CreateLPObject.restype=c_void_p
pLP=nDLL.LP_CreateLPObject()
nDLL.LP_GetLiteralErrorsList.restype=c_int
nDLL.LP_GetLiteralErrorsList.argtypes=[c_void_p,c_char_p,c_char_p]
tone2=nDLL.LP_GetLiteralErrorsList(pLP,b_lang,b_ffff)

b_ffff сдержит следующее :

b'\xd0\xa0\xd1\x9a\xd0\xa0\xd1\x91\xd0\xa0\xc2\xb6\xd0\xa0\xd2\x91\xd0\xa0\xc2\x b0\xd0\xa0\xd0\x85\xd0\xa0\xc2\xb0\xd0\xa1\xd0\x82\xd0\xa0\xd1\x95\xd0\xa0\xd2\x 91\xd0\xa0\xd0\x85\xd0\xa1\xe2\x80\xb9\xd0\xa0\xe2\x84\x96 \xd0\xa1\xd0\x83\xd0\ xa0\xd1\x95\xd0\xa1\xd0\x8b\xd0\xa0\xc2\xb7 \xd0\xa0\xd0\x85\xd0\xa0\xc2\xb5\xd0 \xa0\xc2\xb1\xd0\xa1\xe2\x80\xb9\xd0\xa0\xc2\xbb \xd0\xa0\xd1\x94\xd0\xa0\xd1\x9 5\xd0\xa0\xd0\x85\xd0\xa1\xd0\x8a\xd0\xa0\xd1\x94\xd0\xa0\xc2\xb0\xd0\xa0\xc2\xb 1\xd0\xa0\xc2\xb5\xd0\xa0\xc2\xb6\xd0\xa1\xe2\x80\xa0\xd0\xa0\xc2\xb5\xd0\xa0\xd 0\x86 (ISU) \xd0\xa0\xd0\x86\xd0\xa0\xc2\xb5\xd0\xa0\xd2\x91\xd0\xa0\xc2\xb5\xd0

.......

Видно что это UTF-8

Вот функция с++:

extern "C" __declspec(dllexport) int LP_GetLiteralErrorsList(void *pLP, const char *pLang,const char *pInText){   
    cout<<pInText<<endl;
    return 0;
}

Результат такой:

╨а╤Ъ╨а╤С╨а┬╢╨а╥С╨а┬░╨а╨Е╨а┬░╨б╨В╨а╤Х╨а╥С╨а╨Е╨бтА╣╨атДЦ ╨б╨Г╨а╤Х╨б╨Л╨а┬╖ ╨а╨Е╨а┬╡ ╨а┬▒╨бтА╣╨а┬╗ ╨а╤Ф╨а╤Х╨а╨Е╨б╨К╨а╤Ф╨а┬░╨а┬▒╨а┬╡╨а┬╢╨бтАа╨а┬╡╨а╨Ж (ISU) ╨а╨Ж╨а┬╡╨а ╥С╨а┬╡╨бтАЪ ╨б╨В╨а┬░╨б╨Г╨б╨Г╨а┬╗╨а┬╡╨а╥С╨а╤Х╨а╨Ж╨а┬░╨а╨Е╨а╤С╨а┬╡ ╨а╤Ч╨б╨В╨а╤Х╨а╤ С╨б╨Г╨бтВм╨а┬╡╨б╨Г╨бтАЪ╨а╨Ж╨а╤С╨б╨П ╨а╨Е╨а┬░ ╨б╨В╨а┬░╨а┬╖╨а╤Ш╨а╤С╨а╨Е╨а╤Ф╨а┬╡ ╨а ╤Ч╨а┬╡╨б╨В╨а┬╡╨а╥С ╨а╤Ф╨а╤Х╨б╨В╨а╤Х╨бтАЪ╨а╤Ф╨а╤Х╨атДЦ ╨а╤Ч╨б╨В╨а╤Х╨а╤Ц╨б╨В╨а┬░╨а ╤Ш╨а╤Х╨атДЦ ╨б╤У ╨бтАЮ╨а┬╡╨а╤Ц╨б╤У╨б╨В╨а╤С╨б╨Г╨бтАЪ╨а╤Х╨а╤Ф ╨а╨Е╨а┬░ ╨бтАб╨а┬╡╨а ╤Ш╨а╤Ч╨а╤С╨а╤Х╨а╨Е╨а┬░╨бтАЪ╨а┬╡ ╨а╤Ш╨а╤С╨б╨В╨а┬░.

Подскажите, пожалуйста, что случилось с кодировкой и как восстановить исходную строку (как та которая подавалась на вход)? Со строкой ничего я не делал.

Answer 1

С кодировкой всё в порядке. Результат выглядит ровно так, как должна выглядеть строка в кодировке utf-8 после вывода в консоль с кодировкой cp866. Либо передавайте строку в кодировке соответствующей кодировке консоли

b_ffff = ffff1.encode('cp866')

либо перед запуском изменяйте кодировку консоли

chcp 65001
python script.py

либо доработайте функцию LP_GetLiteralErrorsList так, чтобы она меняла

extern "C" __declspec(dllexport) int LP_GetLiteralErrorsList(void *pLP, const char *pLang,const char *pInText){   
    SetConsoleOutputCP(CP_UTF8);
    setvbuf(stdout, nullptr, _IOFBF, 1024);
    cout << pInText << endl;
    return 0;
}

Упрощённый пример

READ ALSO
шаблонный обьект и Variadic templates

шаблонный обьект и Variadic templates

Создаю по шаблону разные обьекты:

89
Проверка валидности указателя в DLL

Проверка валидности указателя в DLL

Задумал написать DLLЧтобы DLL была универсальной настолько, насколько это вообще возможно - решил использовать минимальный "C" интерфейс и хендлы

86
Занесение пути к файлу в переменную c++

Занесение пути к файлу в переменную c++

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

102
Jquery Проверка наличия ключа объекта

Jquery Проверка наличия ключа объекта

подскажите как проверить наличие ключа в объекте именно на Jquery

106