Змінюй хід війни! Допомагай ЗСУ!

WCHAR to ANSI

🟡 10:00 Відбій тривоги в Харківський район.Зверніть увагу, тривога ще триває у:- Харківський район#Харківський_район
Статус: Offline
Реєстрація: 04.03.2009
Повідом.: 122
  • 🟡 10:00 Відбій тривоги в Харківський район.Зверніть увагу, тривога ще триває у:- Харківський район#Харківський_район
  • #1
Помогите! Нужно извлечь из параметра типа WCHAR (null terminated string) ansi строку....

(VC++)
 
  • 🟡 10:00 Відбій тривоги в Харківський район.Зверніть увагу, тривога ще триває у:- Харківський район#Харківський_район
  • #2
кури Рихтера.

Вторую главу.

P.S. вантуз - постная хуйня. (на правах троля).
 
  • 🟡 10:00 Відбій тривоги в Харківський район.Зверніть увагу, тривога ще триває у:- Харківський район#Харківський_район
  • #3
Возможно WideCharToMultiByte msdn.microsoft.(КОМ)/en-us/library/dd374130(VS.85).aspx спасёт отца русской демократии. Хотя следует отметить, что такая необходимость почти наверняка говорит о проблеме в дизайне.
 
  • 🟡 10:00 Відбій тривоги в Харківський район.Зверніть увагу, тривога ще триває у:- Харківський район#Харківський_район
  • #4
CmbBx_MidiIn->Items->Add(AnsiString(mic.szPname));

То, что подчеркнуто и есто, по сути то, что мне надо - нашел в исходнике на С++ билдер.

Но в VC оно не работает. В инете тож ниче нету. Не пойму...
 
  • 🟡 10:00 Відбій тривоги в Харківський район.Зверніть увагу, тривога ще триває у:- Харківський район#Харківський_район
  • #5
Ну вот WideCharToMultiByte и есть аналог AnsiString, только первое - это системная функция Windows API, а второе - видать, из какой-то C++ Builder'овской библиотеки
 
  • 🟡 10:00 Відбій тривоги в Харківський район.Зверніть увагу, тривога ще триває у:- Харківський район#Харківський_район
  • #6
Ну вот WideCharToMultiByte и есть аналог AnsiString, только первое - это системная функция Windows API, а второе - видать, из какой-то C++ Builder'овской библиотеки

Второе - встроенный билдеровский/делфевский тип, который до 2009-й версии был аналогом обычного string. Начиная с 2009-й string-у уже соответствует WideString. Поэтому конструкция AnsiString(...) это просто cast который прозрачно выполняет компилятор.
А вообще, так делать тоже не правильно, надо юзать WideStringToString().
 
  • 🟡 10:00 Відбій тривоги в Харківський район.Зверніть увагу, тривога ще триває у:- Харківський район#Харківський_район
  • #7
Вообщем метка устройства, возвращаемая API функцией объявлена как WCHAR. Мне это имя нужно перекодировать в тип, который можно увидеть в ListBox-e.
В одном исходнике я увидел решение проблеммы этой функцией, а в другом - "махинациями" с массивами. Только я там ниче не понял. Там данные из Strukture.Label (это то, откуда мне нужно извлечь этот Label) перезаписываются в массив s (к примеру), а потом выводятся в какой то "qlist..." (не помню как точно). Самое главное - хэдэры этого проэкта в Visual C++ я не нашел...


А вот в другом исходнике решение проблеммы я увидел так, как написал в прошлом сообщении.

Ребята! Может кто выводил имя какого-нибудь устройства API функцией типа xxxGetDevCaps? Как преобразовать такой тип данных.

В Visual Basic .Net с этим у меня проблем не возникало, а в C++...

За скорость приходится платить.
 
  • 🟡 10:00 Відбій тривоги в Харківський район.Зверніть увагу, тривога ще триває у:- Харківський район#Харківський_район
  • #8
Вообщем метка устройства, возвращаемая API функцией объявлена как WCHAR. Мне это имя нужно перекодировать в тип, который можно увидеть в ListBox-e.
А как вообще получается, что UI - ANSI версия, а WinAPI используется Unicode версия? Нафига эти сложности? Что мешает использовать Unicode UI? На чём вообще сделан UI?

Ребята! Может кто выводил имя какого-нибудь устройства API функцией типа xxxGetDevCaps? Как преобразовать такой тип данных.
Со списком лень мучаться, но я не вижу проблемы. Я взял проект по умолчанию генерируемый VS 2005 для Win32 Application, добавил нужные хеадеры зависимости в Linker, и в InitInstance добавил такую простую логику:
WAVEINCAPS caps;
waveInGetDevCaps(0, &caps, sizeof(caps));
_tcscpy(szTitle, caps.szPname);
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
И всё отлично работает без каких либо преобразований Unicode <-> ANSI. Заголовок честно выводит "Realtek HD Audio Input".

P.S.
За скорость приходится платить.
Вы уверены, что Вам не хватает скорости именно из-за использования .Net, а не кривых алгоритмов? На самом деле .Net, как и Java, далеко не так уж медленны, как про них некоторые думают.
 
  • 🟡 10:00 Відбій тривоги в Харківський район.Зверніть увагу, тривога ще триває у:- Харківський район#Харківський_район
  • #9
У меня список устройств побольше будет... Мне нужно вывести список Midi In (OUT) портов, которых у меня по 8, более того - мне нужен список для выбора этого порта, чтоб в него данные передавать. Поэтому список позарез нужен.

А по поводу .Net - я наоборот про скорость и функциональность говорю.
 
  • 🟡 10:00 Відбій тривоги в Харківський район.Зверніть увагу, тривога ще триває у:- Харківський район#Харківський_район
  • #10
У меня список устройств побольше будет... Мне нужно вывести список Midi In (OUT) портов, которых у меня по 8, более того - мне нужен список для выбора этого порта, чтоб в него данные передавать. Поэтому список позарез нужен.
Сударь, у нас по-моему, некоторое взаимное непонимание. Цель моего примера показать, что при проектировании без извращений нету необходимости в конвертации Unicode <-> Ansi между UI и WinApi. По-моему, мой пример с этим вполне справляется. А писать полноценный пример со списками, тем более на чистом WinApi - увольте. Это форум и мне за это не платят ;).

Отсюда возникает ряд вопросов, поставленных в предыдущем посте: есть ли у Вас реальные причины для извращений? и на чём (на основе какой библиотеки) сделан UI? В чём причина того, что Вам нужна эта конвертация?
 
  • 🟡 10:00 Відбій тривоги в Харківський район.Зверніть увагу, тривога ще триває у:- Харківський район#Харківський_район
  • #11
Причина в том, что когда я пишу команду
this->ComboBox1->Items->Add(caps.szPname)

компилятор пишет, что невозможно конвертировать тип WCHAR в Object^.

библиотека MMsystem (winmm.dll)
 
  • 🟡 10:00 Відбій тривоги в Харківський район.Зверніть увагу, тривога ще триває у:- Харківський район#Харківський_район
  • #12
Причина в том, что когда я пишу команду
this->ComboBox1->Items->Add(caps.szPname)
компилятор пишет, что невозможно конвертировать тип WCHAR в Object^.

библиотека MMsystem (winmm.dll)
У меня такое впечатление, что, извините за грубость, кто-то не понимает русского языка. Я дважды спросил, на основе какой библиотеки делается UI? MFC, ATL, VCL/CLX, WinForms, Qt, что-то ещё? Извините, но я не знаю, как ещё спросить, что было понятно!

Поскольку ясновидящие, как обычно, в отпуске, придется играть в ясновидящего самому. Судя по комбинации кода из предыдущего поста и упоминания MS VC++ это, вероятно, WinForms. Соответственно Items - ObjectCollection, и значение на экране получается путём вызова ToString для объектов. В принципе можно засунуть любой объект, какой захочется, переопределив ToString, но проще всего - System::String. Для этого нужно всего ничего:
WAVEINCAPS caps;
waveInGetDevCaps(0, &caps, sizeof(caps));
String^ name = gcnew String(caps.szPname);
comboBox1->Items->Add(name);
Замечу, что тут при Unicode конфигурации проекта, а это то, что стоит по умолчанию, конвертации Unicode <-> ANSI не происходит! Происходит конвертация массива WCHAR в объект класса String.

P.S. Не удержусь от ещё одного едкого комментария: нужно читать, что компилятор пишет. Обычно это сильно помогает... как минимум задавать правильные вопросы ;)
 
Останнє редагування:
  • 🟡 10:00 Відбій тривоги в Харківський район.Зверніть увагу, тривога ще триває у:- Харківський район#Харківський_район
  • #13
Спасибо за совет. Я на VC программирую второй день.
По поводу библиотеки - я думал библиотека функции, которую я вызываю.
Я читаю прекрасно, что мне пишет компилятор, ведь из-за этих сообщений программа не компилируется.
А спросил я это, потому что думал - проблема в кодировке.
Нашедши решение в другом исходнике, я и обратился с вопросом.

Я и не думал, что простая процедура добавления нового элемента в ListBox вызовет столько проблем. В Visual Basic с этим какраз проблем не возникало. Возникло в другом, но это уже отдельная история.

В любом случае спасибо.
 
  • 🟡 10:00 Відбій тривоги в Харківський район.Зверніть увагу, тривога ще триває у:- Харківський район#Харківський_район
  • #14
Я и не думал, что простая процедура добавления нового элемента в ListBox вызовет столько проблем. В Visual Basic с этим какраз проблем не возникало. Возникло в другом, но это уже отдельная история.
С VB дружу не очень, но, как я понимаю, там аналогично C# (а скорее всего даже проще), в котором часто можно конвертацию такого рода при P/Invoke возложить на компилятор.
Интересно, какая возникла проблема в VB, которая требует решения именно на C++. Может она тоже вполне решаема более простыми способами?
 
  • 🟡 10:00 Відбій тривоги в Харківський район.Зверніть увагу, тривога ще триває у:- Харківський район#Харківський_район
  • #15
Мне нужно передать из последовательного порта, собраного на специальном чипе (поддерживает нестандартные скорости) сообщения в MIDI порт.
Мало того, что функции библиотеки winmm.dll хреново описываются в VB (в С уже готовых хэдер есть), еще и возникла проблема передачи сообщения.
Первое, что я не понял - тип данных, в котором следует передавать (в С это unsigned char *), второе - в С можно просто написать 0x00403C90 и это будет означать, что в МИДИ порт передалось сообщение "Нота До", а в Васике так написать нельзя.
Да еще и функции сами в инете хреново объявляются (сам же я не знаю список и параметры функций, поэтому искал примеры). Там, например вместо HMIDIIN (Header MIDI IN порта) функция объявлена, запрашивающая переменную типа long, ну, бред короче.

Да и в С все на массивах из чаров, практически, построено, а в Бэйсик все иначе.
Хотя на нем гораздо проще писать, но сложнее находить решение задач, возложеные не на такие слабые плечи, как Васик (работа с большими массивами данных, мультимедиа и т.п.).

К тому же чип, на котором создан преобразователь, работает с библиотекой, адаптированной к С и примеры все на С.

Я С++ только третий день изучаю, но, впринципе, легко уже адаптировался.
Щас отучаюсь от привычки Бэйсиковской объявлять глобальные переменные. :)
 
  • 🟡 10:00 Відбій тривоги в Харківський район.Зверніть увагу, тривога ще триває у:- Харківський район#Харківський_район
  • #16
Попробую прокомментировать по пунктам.
Мало того, что функции библиотеки winmm.dll хреново описываются в VB (в С уже готовых хэдер есть), еще и возникла проблема передачи сообщения.
...
Да еще и функции сами в инете хреново объявляются (сам же я не знаю список и параметры функций, поэтому искал примеры).
Поскольку это WinAPI, то лучшей первичной документаций был и будет MSDN! Начать можно с локальной копии, ставящейся с Visual Studio, которая, кстати, умеет искать и на сайте Посилання видалено

Там, например вместо HMIDIIN (Header MIDI IN порта) функция объявлена, запрашивающая переменную типа long, ну, бред короче.
Это просто у Вас пока мало опыта с WinAPI. На самом деле все Handler'ы (а не "Header"), можно интерпретировать как целочисленные типы данных. Просто в C++ есть средства, которые позволяют дать некоторому типу данных произвольное имя (typedef). Плюс можно сделать ещё дополнительный контроль типов при компиляции, т.е., например, чтобы нельзя было просто так присвоить HMIDIOUT в переменную HMIDIIN. (Если интересно, можно посмотреть определение макроса DECLARE_HANDLE(name), с помощью которого тип HMIDIIN и определён). В других языках, лишённых таких шаманических средств, приходиться использовать "голые" типы данных.

Несколько настораживает то, что используется тип long. Это в каком языке? В зависимости от языка long может означать 32-битное целое (C/C++) или 64-битное (С#, а в VB, как я понимаю Long). Как я вижу HMIDIIN по размеру это DWORD, т.е. 32-битное целое. Если я правильно вижу, Long выглядит как неадекватный тип в VB, хотя может быть адекватным в C.
Многие другие Handler'ы, например все связанные UI, имеют платформо-зависимый размер и равны указателю, например, void* (т.е. 32 бита на 32-битной системе и 64-бита на 64-битных). В этом случае адекватный managed тип это IntPtr.

Первое, что я не понял - тип данных, в котором следует передавать (в С это unsigned char *), второе - в С можно просто написать 0x00403C90 и это будет означать, что в МИДИ порт передалось сообщение "Нота До", а в Васике так написать нельзя.
Я не силён в VB, поэтому трудно правильно прокомментировать. unsigned char * это один из возможных способов описать массив произвольных данных, или некоторую часть потока произвольных данных. При работе с MIDI управлением памятью (структурами MIDIHDR) нужно заниматься самому. Здесь компилятор не в состоянии сам обернуть unmanaged WinAPI в managed код, поскольку выделение и очистка памяти происходит при вызове разных методов xxxPrepareHeader/xxxUnprepareHeader. Одним из возможных решение является использование IntPtr и, возможно, GCHandle.
Здесь в С++ всё равно памятью нужно управлять самому, иначе будет утечка
Я С++ только третий день изучаю, но, впринципе, легко уже адаптировался.
Щас отучаюсь от привычки Бэйсиковской объявлять глобальные переменные.
Удачи!
 
  • 🟡 10:00 Відбій тривоги в Харківський район.Зверніть увагу, тривога ще триває у:- Харківський район#Харківський_район
  • #17
Спасибо большое за советы! Буду меньше язык чесать - больше успею.
Всеравно Вам за эти советы никто не заплатит :).
 
Назад
Зверху Знизу