CreateFile с последовательным соединением имеет нарушение прав доступа - PullRequest
0 голосов
/ 25 марта 2011

Я пытался преобразовать библиотеку последовательной связи в Win32 для использования с аппаратными средствами связи.Я думал, что правильно использовал функцию CreateFile, чтобы открыть соединение, но у меня возникают проблемы с нарушениями доступа в основной функции тестовой программы, которую я написал.initCSACConnection получает HANDLE и передает его main, но основная функция завершается неудачно при попытке присвоить значение локальной переменной там.Сообщение об ошибке «0xC0000005: Место записи нарушения прав доступа 0xfffffff9».Я не понимаю, почему я получаю эту ошибку здесь, я только даю ей пустоту *.

int main ( int argc, char **argv )
{
    HANDLE csacConnection;
    csacConnection = initCSACConnection("COM3");

    return 0;
}

HANDLE initCSACConnection(char* port)
{
    HANDLE portDescriptor;
    portDescriptor = init_port(port, SERIAL_BAUD, "8N1");
    return portDescriptor;
}

HANDLE init_port(char *port, int baud, char *control)
{
    HANDLE portDescriptor;

    portDescriptor = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0,
        0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
    if ( portDescriptor == INVALID_HANDLE_VALUE ) 
    {
        perror("CreateFile") ;
        exit( 9 ) ;
    }

    return portDescriptor;
}

Ответы [ 2 ]

2 голосов
/ 25 марта 2011

Вы можете начать с правильного кода const, заголовочные файлы Windows уже есть.

Затем также проверьте возвращенное значение HANDLE против NULL. Это не должно быть необходимым, но это просто хорошая практика, поскольку NULL не является допустимым значением дескриптора на Win32 (однако 0 является действительным POSIX fd).

Проверьте настройку UNICODE или позвоните CreateFileA явно.

Наконец, убедитесь, что STRICT включен. В указанном вами коде не должно быть никаких символов void*.

И просто для удовольствия распечатайте дескриптор, возвращенный из CreateFile, чтобы вы могли убедиться, что он не будет поврежден при возврате из ваших вспомогательных функций (это может сделать несоответствие соглашения о вызовах).

0 голосов
/ 25 марта 2011

Оказывается, Ганс на правильном пути. У меня был дополнительный код, чтобы попытаться изменить свойства соединения. В конце я прокомментировал команду SetCommState (чтобы уменьшить размер и беспорядок в моем первоначальном посте), полагая, что это устранит любые проблемы, так как остальная часть кода только изменила DCB. Прочитав комментарий Ганса, я закомментировал все после команды CreateFile, и она работала нормально. Вот и весь init_port. Это позволяет initCSACConnection работать правильно, но приводит к нарушению доступа, когда main пытается присвоить возвращаемое значение csacConnection.

HANDLE init_port(char *port, int baud, char *control)
{
    HANDLE portDescriptor;
    DCB t;
    int bit, stop ;
    char par ;

    portDescriptor = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0,
        0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
    if ( portDescriptor == INVALID_HANDLE_VALUE ) 
    {
        perror("CreateFile") ;
        exit( 9 ) ;
    }

    /* Strip the control parameters from the control string */
    sscanf_s( control, "%1d%1c%1d", &bit, &par, &stop ) ;

    /* Read in the current port attributes */ 
    FillMemory(&t, sizeof(t), 0);
    if ( GetCommState(portDescriptor, &t) == 0 ) 
    {
        perror("GetCommState") ;
        printf ("opened port:(%s) descriptor:%d speed:%d c:%1d%c%1d\n", 
            port, portDescriptor, baud, bit, par, stop );
        exit( 2 ) ;
    }

    /* Set the # bits, parity and stop bits */
    if ( (bit < 5) || (bit > 8) ) 
    {
        fprintf(stderr, "Invalid character bit size:%d [5-8]\n",bit ) ;
        exit( 2 ) ;
    }

    if ( par == 'E' || par == 'e' ) 
    {
        t.Parity = EVENPARITY ; /* Even parity */
        t.fParity = FALSE ;  /* Enable parity check */
    }
    else if ( par == 'O' || par == 'o' ) 
    {
        t.Parity = ODDPARITY ; /* Odd parity */
        t.fParity = TRUE ; /* Enable parity check */
    } else {
        t.fParity = FALSE;
    }

    if (stop == 1)
        t.StopBits = ONESTOPBIT;
    else if (stop == 2)
        t.StopBits = TWOSTOPBITS ; /* Two stop bits */

    /* Set the baud rate */
    switch(baud)
    {
        case 1200:
            t.BaudRate = CBR_1200 ;
            break;
        case 2400:
            t.BaudRate = CBR_2400 ;
            break;
        case 4800:
            t.BaudRate = CBR_4800 ;
            break;
        case 9600:
            t.BaudRate = CBR_9600 ;
            break;
        case 19200:
            t.BaudRate = CBR_19200;
            break;
        case 38400:
            t.BaudRate = CBR_38400;
            break;
        case 57600:
            t.BaudRate = CBR_57600;
            break;
        case 115200:
            t.BaudRate = CBR_115200;
            break;
        case 256000:
            t.BaudRate = CBR_256000;
            break;
    }

    if ( SetCommState(portDescriptor, &t) == 0 ) 
    {
        perror("SetCommState") ;
        exit( 2 ) ;
    }

    return portDescriptor;

}
...