2017-11-15 9 views
0

シリアル回線のファイル記述子である新しいソースをg_main_loopに追加しようとしました。シリアルリンクで読み込みを待っているデータの通知

私はこのコードを試してみてください。

GError* error; 
GIOChannel* channel; 
channel=g_io_channel_unix_new(fd_serial_line_dev); 
g_io_add_watch(channel, G_IO_IN, cb_1, NULL); 
g_io_channel_set_close_on_unref(channel, TRUE); 
g_io_channel_set_encoding(channel, NULL, &error); 
g_io_channel_set_buffered(channel, FALSE); 

コールバックは次のとおりです。

gboolean cb_1 (GIOChannel *source, GIOCondition condition, gpointer data) 
{ 
    gchar** line=NULL; 
    GIOStatus status; 
    GError* error; 

    printf("cb\n"); 

    status=g_io_channel_read_line(source, line, NULL, NULL, &error); 

    if(G_IO_STATUS_NORMAL == status) 
    { 
    printf("callback : data : %s\n", *line); 
    g_free(*line); 
    //g_io_channel_seek_position(source, 0, G_SEEK_CUR, NULL); 
    } 

    return TRUE; 
} 

私はシリアル回線上のデータを送信するとき、私はcb_1たびに呼び出す無限ループを得ます。

私は私のミスであり、私はシリアルラインのファイルディスクリプタ内の読み取りは、次のグラムメインループの反復中にコールバックに呼び出しを停止するsuffisantされることが予想表示されない...

+0

私はチャンネルを閉じるためにエラーでfalseを返しているはずです。 – TheAschr

+0

私は試して、このソリューションのコールバックは、たとえ新しいcaracterが来ているとしても呼び出されることはありません。私にとって、FALSEを返すことは、イベントソースを削除する必要がある場合に便利です –

答えて

1

に()g_source_removeを呼び出す場合、GLibののg_io_add_watch方法をポーリングするファイルディスクリプタを追加します()。/devファイルのポーリングは、ソケット記述子や通常のファイルと同じではありません。ドライバーの構造体構造をチェックして、ドライバーがポーリング操作をサポートしているかどうかを確認してください。通常は、カスタムドライバを使用していない限りサポートします。また、あなたのコードを他の/ devファイルとクロスチェックしてください。

コールバックのg_io_channel_read_lineから返されるステータスがG_IO_STATUS_AGAINであることを確認してください。これはリソースが一時的に利用できないことを意味します。そのため、ファイルディスクリプタでイベントが発生しましたが、ドライババッファから読み込むための即時データはありません。

1

てみてくださいg_io_add_watchの後にg_io_channel_unref(channel) immediatleyを追加してください。次に、あなたのコールバックで新しい

if(G_IO_STATUS_EOF == status) 
return FALSE; 

g_io_channel _ * _を(追加)1の参照カウントを持つGIOChannel オブジェクトを返します。 g_io_add_watch()はさらに 参照カウントを追加します - もしそれを1減らすと、 は切断され、 コールバックがFALSEを返すと関連するGSourceオブジェクトが削除されます。これはファイルの終わりを検出したときに行うべきです。 あなたがg_io_add_watchの戻り値()Linuxの

関連する問題