0

ハードウェアとの通信に使用するために、シリアル通信ライブラリをWin32に変換しようとしています。CreateFile関数を適切に使用して接続を開いたと思いましたが、作成したテストプログラムのメイン関数でアクセス違反に問題があります。initCSACConnectionはHANDLEを取得してメインに渡しますが、ローカル変数に値を割り当てようとすると、メイン関数が失敗します。エラーメッセージは「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;
}
4

2 に答える 2

2

あなたはコードをconst正しくすることから始めるかもしれません、Windowsヘッダーファイルはすでにそうです。

次に、返されたHANDLEに対しても確認しNULLます。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 に答える