- ベストアンサー
ReadFile(GPSとの通信)Win7での挙動
- GPS(Garmmin GPSmap 60Cx)との通信において、Windows 7では問題が発生しています。ReadFile関数を実行してデータを取得する際に、最初の3つのウエイポイントしか取得できず、残りの6つは取得できません。しかし、Sleep(1)の処理を追加すると、全てのデータを正常に取得することができます。
- 通信方法を非同期で行うために、CreateFile関数でFILE_FLAG_OVERLAPPEDを指定し、DeviceIoControlとReadFile関数にOverlapped構造体を指定した場合でも、問題が解決せず、Sleep(1)が必要となります。
- Windows 7のマシンスペックがWinXPと比べて高速なため、ReadFile関数が完了して次の処理を行う前に一定の待機時間が必要となります。Win7のPCはCore i5-2500 3.3GHz、WinXPのPCはPentium4 3GHz程度のスペックです。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
関連するQ&A
- ReadFileについて
はじめまして。 コマンドラインから実行可能なRS232C通信プログラムを Cで作成しています。 ハイパーターミナルからCOM2に文字を出力して ReadFileで取得した文字列を画面にはき出すというだけの 「Hello,World!」のような簡単なプログラムなのですが ReadFileの動作結果に思うようなものが得られず困っています。 お知恵をお貸しください。 読込結果がおかしいのです。 リターンキー以外は何を入力しても「7F」が返ってきてしまいます (リターンキー入力の場合も正常値ではありません)。 また、入力も無視されたり、認識されたりで動作も不安定です。 ReadFile自体のエラーは発生しません。 よろしくお願いいたします。 Borland C++ Compiler 5.5 Windows2000(実際に動作させたいのはWin95上です) 以下、コードです。 DWORD dwErrors; // エラー情報 COMSTAT ComStat; // デバイスの状態 DWORD dwCount; //受信データのバイト数 DWORD dwRead; // ポートから読み出したバイト数 unsigned char pszBuf[30];// 受信バッファ while(1){ ClearCommError(hComm, &dwErrors, &ComStat); dwCount = ComStat.cbInQue; if (0 >= dwCount) continue; memset(pszBuf,'\0',sizeof(pszBuf)); if (ReadFile(hComm, pszBuf, dwCount, &dwRead, NULL)){ if (dwRead > 0) { if (pszBuf[0] == '\r') break; printf("%%s : %s\n",pszBuf); }else{ break; } } }
- ベストアンサー
- C・C++・C#
- 非同期のプロセス間通信(パイプ)で全データ受信する
こんにちは。 非同期のプロセス間通信(パイプ)で詰まっています。 環境はWindowsで処理系はC++(Win32)です。 スレッドを用意して、 hPipe = ::CreateFile( L"\\\\.\\pipe\\pipename", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL ) ; で作成し、OVERLAPPED構造体を // ZeroMemory( &so, sizeof( OVERLAPPED )) ; sOverlapped.hEvent = ::CreateEvent( NULL, FALSE, FALSE, NULL ) ; として、 const size_t bufsize = 16 ; BYTE buffer[ uBufSize ] ; DWORD dwNumberOfBytesRead ; bRet = ::ReadFile( hPipe, buffer, bufsize, &dwNumberOfBytesRead, &so ) ; で読み込みをしています。ReadFile関数はすぐ戻りbRetはFALSEで返ってくるため、GetLastErrorを調べて、 switch( ::GetLastError()) { case ERROR_IO_PENDING : bRet = ::GetOverlappedResult( hPipe, &so, &dwNumberOfBytesRead, FALSE ) ; break ; } としてWaitForMultipleObjectsでsOverlapped.hEventがシグナル状態になったら取得したデータの処理をしています。 シグナル状態になるならないに関わらず、上記のReadFileとGetOverlappedResultはループでぐるぐる回しています。 上記の状態で短いデータならよかったのですが、上記のReadFileで読み込み最大サイズの16バイトを超えてしまとうと、 残りの部分のみしか取得できませんでした。 0123456789ABCDEFabcdefg というデータを受信しようとしたとき、後半のabcdefgだけしか取得できませんでした。 すべてのデータを正しく取得するにはどのようにしたらよいのでしょうか?
- 締切済み
- C・C++・C#
- PICとPCでのシリアル通信
PICとPC間でのシリアル通信を行ってるんですけどうまくいきません。ハイパーターミナル使えばうまくいくんでPIC側のソース(C)はうまくいってると思います。ハイパーターミナルを使わずにシリアルの送受信のプログラム(C++)を組んでるんですけどうまくいかなくて。。。 アドバイスなどお願いします!!どこが違うんでしょうか。。。 ●PC側のソース(C++) #include "stdafx.h" #include <stdlib.h> #include <windows.h> #include<iostream> using namespace std; #define COM_PORT_NAME "COM1" #define BAUD_RATE 9600 #define BYTE_SIZE 8 #define PARITY EVENPARITY #define STOP_BIT TRUE #define F_PARITY ONESTOPBIT HANDLE hComm; // シリアルポートとの通信ハンドル bool ComInit() { // シリアルポートを開ける hComm = CreateFile( COM_PORT_NAME, /* シリアルポートの文字列 */ GENERIC_READ | GENERIC_WRITE, /* アクセスモード:読み書き */ 0, /* 共有モード:他からはアクセス不可 */ NULL, /* セキュリティ属性:ハンドル継承せず */ OPEN_EXISTING, /* 作成フラグ: */ FILE_ATTRIBUTE_NORMAL, /* 属性: */ NULL /* テンプレートのハンドル: */ ); if (hComm == INVALID_HANDLE_VALUE) { printf("シリアルポートを開くことが出来ませんでした。\n"); return false; } // 通信属性を設定する DCB dcb; GetCommState(hComm, &dcb); /* DCB を取得 */ dcb.BaudRate = BAUD_RATE; dcb.ByteSize = BYTE_SIZE; dcb.Parity = PARITY; dcb.fParity = STOP_BIT; dcb.StopBits = F_PARITY; SetCommState(hComm, &dcb); /* DCB を設定 */ return true; } void ComEnd() { // ハンドルを閉じる CloseHandle(hComm); } bool WriteData(char *buff, unsigned int data_size) { DWORD dwWritten; /* ポートへ書き込んだバイト数 */ WriteFile(hComm, buff, data_size, &dwWritten, NULL); if (dwWritten!=data_size) { printf("データの送信に失敗しました。\n"); return false; } return true; } bool ReadData(char *buff, unsigned int max_size) { DWORD dwErrors; /* エラー情報 */ COMSTAT ComStat; /* デバイスの状態 */ DWORD dwCount; /* 受信データのバイト数 */ DWORD dwRead; /* ポートから読み出したバイト数 */ ClearCommError(hComm, &dwErrors, &ComStat); dwCount = ComStat.cbInQue; if (dwCount > max_size) { printf("バッファサイズが足りません。\n"); return false; } ReadFile(hComm, buff, dwCount, &dwRead, NULL); if (dwCount != dwRead) { printf("データの受け取りに失敗しました。\n"); return false; } return true; } int main(int argc, char* argv[]) { char ch; while(1){ cin >> ch; printf("入力 %c\n", ch); ComInit(); WriteData(&ch, strlen(&ch)); ReadData(&ch, strlen(&ch)); ComEnd(); } return 0; }
- 締切済み
- その他(インターネット接続・通信)
- ReadFileの読み込みエラーについて
こんばんは Win32 APIでプログラミングをやっているのですが、そのAPIの中でReadFileというものがありますよね? この関数でエラー値が出力され、第二引数としてBITMAPINFO構造体に格納するはずの値がそのままです。 以下に一部ソースを載せます BOOL Cell_Init( HINSTANCE hInstance ) { BITMAPINFO bmi2; HANDLE hFile; DWORD dwBytes; // 作成するビットマップの情報を設定する BITMAPFILEHEADER bmpFileHeader; BITMAPINFO bmi; // ビットマップのハンドルと、作成したバッファの先頭アドレスを取得 void* pImage; HBITMAP hBitmap; // デスクトップのDCを得る HDC tmpDC = GetDC(GetDesktopWindow() ); // HBITMAPにHDCを結びつける g_hdc_cell = CreateCompatibleDC( tmpDC ); DWORD er; hFile = CreateFile("cointos.bmp", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); er = GetLastError(); if(hFile == INVALID_HANDLE_VALUE) return 0; ReadFile(hFile, &bmpFileHeader, sizeof(BITMAPFILEHEADER), &dwBytes, NULL); er = GetLastError(); if(bmpFileHeader.bfType != 0x4D42) { MessageBox(NULL, TEXT("This is not a bitmap file"), NULL, MB_OK); return FALSE; } //ここでbmi2に格納される値が格納されていない(そのためでかい値のまま) そのためCreateDIBSectionではエラーを起こす ReadFile(hFile, &bmi2, bmpFileHeader.bfOffBits - dwBytes, &dwBytes, NULL); er = GetLastError(); // ここの部分でエラー値998が出ます hBitmap = CreateDIBSection(tmpDC, &bmi2, DIB_RGB_COLORS, (LPVOID*)&pImage, NULL, 0); ReadFile(hFile,pImage, bmpFileHeader.bfSize - bmpFileHeader.bfOffBits, &dwBytes, NULL); SelectObject( g_hdc_cell, hBitmap ); CloseHandle(hFile); ReleaseDC(GetDesktopWindow(), tmpDC); return TRUE; } なぜこうなるんでしょうか? bmi2はBITMAPINFO構造体でローカルで宣言しています。これがポインタだと大丈夫なんですが なぜ変数ではダメなのか分かりません。 あらかじめ確保されているスタック領域の容量限界でも ないと思うのですが。 分かる方がいらっしゃったらよろしくお願いします。 開発環境はVS.2005 です。
- ベストアンサー
- C・C++・C#
- java でソケット通信をするとき
javaでソケット通信をするとき、 //データ受け取り byte[] buffer = new byte[2048]; try { int size = 0; while (size <= 0) { size = is.read(buffer); } receiveStr = new String(buffer, 0,size, "UTF8"); } catch (IOException e) { e.printStackTrace(); } のようにしていますが、これだと文字数にして一度におくれる容量はどのくらいでしょうか? また、それらを増やすにはどうしたらいいでしょうか?
- ベストアンサー
- Java
- COMポート 名前を取得する方法
VC++2008Express Win32Api COMポートの名前Portnameを調べて Listboxに表示させたいと思います。 以下のようにレジストリからフレンドリーネームとかは 取得できるようになったのですが レジストリのフォルダのVIDとかなんちゃらの部分の値は取得できるのですが その1階層下のParameterの中にあるPortNameを取得したいです。 要するにCOM6などの部分だけが欲しいです。 どなたか、ご教示ください。よろしくお願いします。 BYTE Buffer[256]; DWORD Length = 0; SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_COMPORT, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); int ret = SetupDiEnumDeviceInfo( hDevInfo, 0, &DeviceInfoData ); SetupDiGetDeviceRegistryProperty( hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC, NULL, Buffer,sizeof(Buffer),&Length ); MessageBox( NULL,(LPCWSTR)Buffer , 0 , MB_OK ); SetupDiDestroyDeviceInfoList(hDevInfo);
- ベストアンサー
- C・C++・C#
- VC++でのシリアル通信が上手くいきません。
ArduinoからPCへ送られてくる信号を表示するコンソールアプリケーションを VC++で試作しているのですが、ReadFile()関数でデータを読み取ろうとするとうまくいきません。 どうすればうまくいくでしょうか? どなたかお詳しい方がおられましたら回答をよろしくお願いします。 コードは以下の通りです。 #include <Windows.h> #include <stdlib.h> #include <stdio.h> HANDLE arduino; bool Ret; void main(void){ BYTE data = 1; //1.ポートをオープン arduino = CreateFile("COM3",GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(arduino == INVALID_HANDLE_VALUE){ printf("PORT COULD NOT OPEN\n"); system("PAUSE"); exit(0); } //2.送受信バッファ初期化 Ret = SetupComm(arduino,1024,1024); if(!Ret){ printf("SET UP FAILED\n"); CloseHandle(arduino); system("PAUSE"); exit(0); } Ret = PurgeComm(arduino,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); if(!Ret){ printf("CLEAR FAILED\n"); CloseHandle(arduino); exit(0); } //3.基本通信条件の設定 DCB dcb; GetCommState(arduino,&dcb); dcb.DCBlength = sizeof(DCB); dcb.BaudRate = 9600; dcb.fBinary = TRUE; dcb.ByteSize = 8; dcb.fParity =NOPARITY; dcb.StopBits = ONESTOPBIT; Ret = SetCommState(arduino,&dcb); if(!Ret){ printf("SetCommState FAILED\n"); CloseHandle(arduino); system("PAUSE"); exit(0); } //4.受信 DWORD dwSendSize; DWORD dwErrorMask; int i=0; while(i<30) { Ret = ReadFile(arduino,&data,1,&dwSendSize,NULL); if(!Ret){ printf("RECEIVE FAILED\n"); CloseHandle(arduino); system("PAUSE"); exit(0); } printf("data=%c\n",data); i++; Sleep(100); } printf("FINISH\n"); CloseHandle(arduino); system("PAUSE"); }
- 締切済み
- C・C++・C#
- 変数のタイプ
Active Basicを使ってプログラムを書いています。 そのときに、変数というものがいまいち理解できなく、感覚で適当にしてしまいます。 たとえば、ファイルをを開くのダイアログボックスでファイルパスを取得するとき、Active Basicの本では、その文字列を格納するのに、 『Byte』を使っていました。 Dim buffer[MAX_PATH-1] As Byte といった風です。 しかし、本には、 バイト数:1 値の範囲:0~255 と書いてあります。 文字列を取得する場合はStringを使うのではないでしょうか? Byteでも、文字列を格納できるのでしょうか? 他にも、LongやDWordやIntegerやSingle、Dobleといったものがありますが、どう使い分けていいのかがわかりません。 すみませんが、分かる方、いらっしゃいましたらご教授願えませんでしょうか?
- ベストアンサー
- その他(プログラミング・開発)
- ReadFileでエラーが出ます。
シリアルポートで非同期でバイナリを受信するプログラムを作成しています。 受信部分は以下のソースです。これで実行すると「データ受信エラー」のダイアログが出ます。 GetLastErrorでは998(メモリ ロケーションへのアクセスが無効です。)が得られました。 ネットで調べましたが何が原因かも分かりません・・。 どうかアドバイスお願いします。 HANDLE hEvent; hEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); OVERLAPPED old; ZeroMemory( &old, sizeof(old) ); old.Offset = 0; old.OffsetHigh = 0; old.hEvent = hEvent; DWORD dwCount; char* rdBuf; DWORD dwRead; if(!ReadFile(hCom,rdBuf,dwCount,&dwRead,&old)){ if(ERROR_IO_PENDING == GetLastError()){ GetOverlappedResult(hCom,&old,&dwRead,TRUE); } else MessageBox("データ受信エラー","試作1",MB_ICONSTOP); }
- ベストアンサー
- C・C++・C#
- ファイルポインタfpを、何バイト読んだかカウンタとして使うには?
ファイルポインタfpを、何バイト読んだかカウンタとして使うには?どうしたら良いか教えてください。binary fileをオープンして、1Byteずつc=fgetc(fp); を繰り返し読込み特定の処理します。数百万バイトを読んだあたりで、こけるので、何バイト目あたりでこけているのか知りたいというのが動機です。 fp構造体の中で、今、ファイルの冒頭から何バイト読んだところ、という情報を引っ張り出して1Byte読み込むごとに(ずらずらとでいいので)表示したいです。fp->current_byte とかいう情報があるように想像するのですが、どうでしょうか。以下に、#include<stdio.h>の中で、FILE を引用します。 typedef struct { unsigned char *curp; /* Current active pointer */ unsigned char *buffer; /* Data transfer buffer */ int level; /* fill/empty level of buffer */ int bsize; /* Buffer size */ unsigned short istemp; /* Temporary file indicator */ unsigned short flags; /* File status flags */ wchar_t hold; /* Ungetc char if no buffer */ char fd; /* File descriptor */ unsigned char token; /* Used for validity checking */ } FILE; /* This is the FILE object */
- 締切済み
- C・C++・C#
- ぷららの解約手続きについてご相談です。現在自宅と仕事場とぷららを2つ契約しているのですが、自宅を引っ越すことになりました。しかし、マイページで確認したところ、仕事場の住所しか見れません。オペレーターにもつながらず、解約手続きができない状況です。このまま解約手続きをしたら、仕事場の回線も解約されてしまうのか不安です。どのようにすればよいでしょうか?
- ぷららの解約について質問があります。現在、自宅と仕事場の2箇所でぷららを契約していますが、自宅の方を引っ越すことになりました。しかし、解約手続きをしようとしたところ、マイページで仕事場の住所しか確認することができません。オペレーターにもつながらず、どうすれば解約手続きができるのか困っています。もし解約手続きをしたら、仕事場の回線も解約されてしまうのでしょうか?アドバイスをお願いします。
- ぷららの解約について相談があります。現在、自宅と仕事場の2つをぷららで契約していますが、自宅を引っ越すことになりました。ところが、解約手続きをしようとしたところ、マイページで仕事場の住所しか確認することができません。オペレーターにもつながらず、困っています。もし解約手続きをしたら、仕事場の回線も解約されてしまうのでしょうか?どうすればいいでしょうか?お教えください。
お礼
ご回答ありがとうございます。 >「まだデータが届いていない(or そう判断された場合)」読み込みバッファの中身は、「なし」になりま>す。 確かに、バッファの中身がなしになっていました。7のマシンが「速い」ためのようです。 そもそも、returnbyteが0で終了条件としていましたが、送信データに終了IDが送信されてくることがわかりました。 終了IDまでデータを読み続け、returnbyte0は、読み飛ばすことでデータをすべて取得することができました。 どうもありがとうございました。