具有串行通信的CreateFile具有访问冲突

时间:2011-03-24 22:55:01

标签: winapi handle access-violation createfile

我一直在尝试将串行通信库转换为Win32,以便与硬件通信。我认为我已正确使用CreateFile函数来打开连接,但我在我编写的测试程序的main函数中遇到了访问冲突问题。 initCSACConnection获取HANDLE并将其传递给main,但是当尝试将值分配给那里的局部变量时,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 个答案:

答案 0 :(得分:2)

您可以从使代码const开始 - 正确,Windows头文件已经是。

然后,还要针对HANDLE检查返回的NULL。这不是必需的,但这只是一个好习惯,因为NULL不是Win32上的有效句柄值(0是一个有效的POSIX fd)。

检查您的UNICODE设置或明确致电CreateFileA

最后,确保已启用STRICT。您所显示的代码中不应有任何void*

只是为了好玩,打印出从CreateFile返回的句柄,这样你就可以确保它从帮助函数返回时没有被破坏(调用约定不匹配就可以了)。

答案 1 :(得分:0)

原来汉斯走在了正确的轨道上。我有额外的代码来尝试修改连接的属性。我最后注释掉了SetCommState命令(以减少我的初始帖子的大小和混乱),认为这将删除任何问题,因为其余的代码只修改了DCB。在阅读了Hans的评论之后,我在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;

}