0

我一直在尝试将串行通信库转换为 Win32 以用于与硬件通信。我认为我已经正确地使用了 CreateFile 函数来打开一个连接,但是我在我编写的测试程序的主函数中遇到了访问冲突的问题。initCSACConnection 获取 HANDLE 并将其传递给 main,但是在尝试将值分配给那里的局部变量时 main 函数失败。错误消息是“0xC0000005:访问冲突写入位置 0xfffffff9”。我不明白为什么我在这里收到这个错误,我只是给它一个 void*。

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;
}
4

2 回答 2

2

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

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

检查您的 UNICODE 设置或CreateFileA明确调用。

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

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

于 2011-03-24T23:02:58.420 回答
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;

}
于 2011-03-25T16:03:09.390 回答