Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Полное имя COM-порта на Си?
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
Legotron
Доброго времени суток!

Использую CBuilder.
Подскажите пожалуйста как записать полное имя COM-порта на Си в строку??
должно быть:
Код
"\\.\COMx"

варианты:
Код
AnsiString Com_txt = "\\.\COM";
AnsiString Com_txt = "\\\\.\\COM";

не позволяют написать необходимую строку sad.gif
что приводит к ошибкам открытия порта

Помогите господа, тупая проблема, но уже начинает раздражать...
733259
Я открываю просто "COM1", "COM2", собираю mingw, может в CBuilder не так, но вроде не должно.
ReAl
Просто "COM1" годится только до COM4 (или COM9, а проблемы на двузначных начинаются - забыл уже).
Я формирую строку для открывания так:
Код
    wsprintf( str, "\\\\.\\COM%d", num);
где str - буфер, которые потом передаётся в CreateFile, num - номер порта.
Всякие там COM23, на которые любят садится FTDIные преобразователи USB-COM, только так и открыть.
Почему не работает "\\\\.\\COM" в AnsiString - не знаю, билдером никогда не пользовался.
Компилирую wingw32, причём без никаких wchar-ов/юникодов, для моих dll-ек, использующихся с дельфийскими программами - этого достаточно (из конфига своего прочёл номер порта, открыл и всё).
UniBomb
Имя порта можно указывать и просто как "Comx", просто нао делать так:


Код
AnsiString portname = "Com1";
CreateFile(portname.c_str(), ....
zltigo
Цитата(UniBomb @ Dec 17 2008, 20:43) *
Имя порта можно указывать и просто как "Comx"

Тут уже написали как и почему. Перечитайте.


Цитата(ReAl @ Dec 17 2008, 19:29) *
wsprintf(

wsprintf() - то зачем? На чистом API все на 8bit кодировке работает.
ReAl
Цитата(zltigo @ Dec 17 2008, 20:42) *
wsprintf() - то зачем? На чистом API все на 8bit кодировке работает.
Это w означает не widw char, а то, что функция из винды (как бы не ещё с win3 тянется), wsprintf на 8 битах и работает. Это тот же sprintf, только из user32.dll
Иногда леплю по привычке для уменьшения размера бинарника.
В принципе сейчас как-то всё равно, mingw32-gcc пришивает sprintf из болтающейся в windows/system32 msvcrt.dll, ни в бинарнике места больше по сравнению с wsprintf не выходит, ни библиотек дополнительных тянуть не надо.
*antzol*
Работаю в билдере, открываю примерно так:
Код
AnsiString PortName;
...
PortName = "COM23";
...
port = CreateFile(PortName.c_str(),
                       GENERIC_READ | GENERIC_WRITE, 0,
                       NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
zltigo
Цитата(ReAl @ Dec 17 2008, 22:35) *
Это w означает не widw char, а то, что функция из винды....

А.....! вспомнил, действительно любят лепить ко всему, чего не поподя.
ReAl
Цитата(*antzol* @ Dec 17 2008, 21:48) *
Работаю в билдере, открываю примерно так:
Код
AnsiString PortName;
...
PortName = "COM23";
...
port = CreateFile(PortName.c_str(),
                       GENERIC_READ | GENERIC_WRITE, 0,
                       NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
Ну не знаю. Может, билдер сильно умный wink.gif.
Но вот текст завалялся, примерчик человеку делал по зажиганию светодиодов:
Код
#include <windows.h>
#include <stdio.h>

int main(int ac, char **av)
{
    int key;
    HANDLE hCom;
    
    if( ac < 2) {
        printf( "Use: test COMNAME\n");
        return 1;
    }
        
    hCom = CreateFile( av[1], GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
    
    if( hCom == INVALID_HANDLE_VALUE ) {
        printf( "Can't open %s", av[1]);
        return 1;
    }

    printf( "use r/R, d/D, b/B keys for clear/set RTS, DTR and BREAK state, q for quit (press CR after key)\n");
    
    while( (key = getchar()) != 'q' ) {
        switch(key) {
        case 'D':   EscapeCommFunction( hCom, SETDTR);  break;
        case 'd':   EscapeCommFunction( hCom, CLRDTR);  break;
        case 'R':   EscapeCommFunction( hCom, SETRTS);  break;
        case 'r':   EscapeCommFunction( hCom, CLRRTS);  break;
        case 'B':   SetCommBreak( hCom);    break;
        case 'b':   ClearCommBreak( hCom);  break;
        }
    }
        
    CloseHandle(hCom);
    
    return 0;
}
И вона скиншоты наличных COM-портов и вызовов теста с разными параметрами (com5 берёт, значит, дело в количестве цифр).
Нажмите для просмотра прикрепленного файлаНажмите для просмотра прикрепленного файла

Кстати, прямые слеши в путях ("//./com22") тоже работают довольно давно, но не везде (в fopen() работают, в командной строке в dir - нет, оно буквы после / как ключи воспринимает), поэтому я лучше уж напишу с С-шной строке \\ для передачи каждого '\', и не буду путаться.

upd:
распаковал из архива BC++ 5.02, скомпилировал приведенній выше текст, результаты прогона совпадают 1:1
*antzol*
Цитата
Ну не знаю. Может, билдер сильно умный .

Ну я тоже не знаю. laughing.gif
Я ж ничего своего не придумывал, а делал всё по примерам из книжки Архангельского (Приемы программирования в C++ Builder 6 и 2006), и никаких проблем с портами выше COM4 не возникало. smile.gif
777777
Цитата(ReAl @ Dec 17 2008, 22:35) *
Это w означает не widw char, а то, что функция из винды (как бы не ещё с win3 тянется), wsprintf на 8 битах и работает. Это тот же sprintf, только из user32.dll

Кто вам сказал этих глупостей? smile.gif wsprintf - это функция для юникодных символов, а то, о чем ты говоришь, начинается с буквы 'l'. И использовать ее нет никакой необходимости - на размер бинарника это не влияет, так как к нему не лепится, а берется из msvcrt.dll
ReAl
Цитата(777777 @ Dec 18 2008, 06:38) *
Кто вам сказал этих глупостей? smile.gif wsprintf - это функция для юникодных символов, а то, о чем ты говоришь, начинается с буквы 'l'.
А Вы не могли бы цитатку из MSDN ? А то в статье printf, wprintf сказно, что wprintf - wide character версия (и формат у второй имеет тип const wchar_t * ), а в статье про wsprintf об этм ни слова. И приёмная строка да формат у wsprintf - типа LPSTR да LPCSTR соответственно, ещё от win3.х тянется небось... И живут они с wvsprintf в user32.dll, в отличие от wprintf, которая часть библиотеки VC и живёт в msvcrt.dll. И даже статьи про них в разных разделах - про wsprintf - в Platform SDK а про wprintf - в разделе про VC++.

Ну да, зглянул на компакт со старючим - в программах для win3.x у меня wsprintf был. "а то, о чём ты говоришь" - это swprintf

А префикс l - это lstrcpy(), lstrcpy() и компания. Никакого lsprintf в MSDN и в помине нет.

Цитата(777777 @ Dec 18 2008, 06:38) *
И использовать ее нет никакой необходимости - на размер бинарника это не влияет, так как к нему не лепится, а берется из msvcrt.dll
777777 не читатель, 777777 писатель? Я об этом сам написал в том же сообщении, которое было Вами процитировано. Парой строк ниже.
И там же написал, что это просто глупая привычка, которая иногда проскакивает, под BC3.1 да WIN3.x размер бинарника это увеличивало, а я не так много пишу под WIN, чтобы эта привычка ушла навсегда.
MALLOY2
в билдере 6 я так открываю

Код

  String s;
  COMMTIMEOUTS timeouts;
  DCB CommCtrl;
  HANDLE htmp;

  s = "\\\\.\\COM" + IntToStr(PortNumber);
  htmp = ::CreateFile(s.c_str(),GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);


Цитата
Я открываю просто "COM1", "COM2", собираю mingw, может в CBuilder не так, но вроде не должно.


можно и так токо от COM1 до COM9. COM10 уже не откроеш.
ReAl
Цитата(*antzol* @ Dec 18 2008, 04:45) *
Ну я тоже не знаю. laughing.gif
Я ж ничего своего не придумывал, а делал всё по примерам из книжки Архангельского (Приемы программирования в C++ Builder 6 и 2006), и никаких проблем с портами выше COM4 не возникало. smile.gif

Странно... И таки COM23 тоже, не только COM7 какой-нибудь?
*antzol*
Про com23 не помню, но выше десятого точно открывал.
777777
Цитата(ReAl @ Dec 18 2008, 09:14) *
А Вы не могли бы цитатку из MSDN?

Да, точно, юникодная версия - это swprintf.

А вообще, хотя COM-порт открывается как обычный файл, работа с ним ведется особым образом, для него создается специальная структура - DCB блок, в MSDN об этом подробно написано в описании функции CreateFile


Цитата(ReAl @ Dec 18 2008, 00:18) *
И вона скиншоты наличных COM-портов и вызовов теста с разными параметрами (com5 берёт, значит, дело в количестве цифр).

Может это глюк билдера, но в VC я открывал порты под именами вида COM001 и все работало.
Vlad27
Цитата(Legotron @ Dec 17 2008, 17:59) *
Доброго времени суток!

Использую CBuilder.
Подскажите пожалуйста как записать полное имя COM-порта на Си в строку??
должно быть:
Код
"\\.\COMx"

варианты:
Код
AnsiString Com_txt = "\\.\COM";
AnsiString Com_txt = "\\\\.\\COM";

не позволяют написать необходимую строку sad.gif
что приводит к ошибкам открытия порта

Помогите господа, тупая проблема, но уже начинает раздражать...


Посмотрел у себя в рабочей программке.
Код
  String portname; //имя порта (например, "COM1", "COM2" и т.д.)
   DCB dcb;         //структура для общей инициализации порта DCB

  portname = "\\\\.\\" + Form1->ComboBox1->Text; //получить имя выбранного порта

C++Builder6. Так прокатывает.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.