使用PCによるアプリケーション実行時のエラー発生について – 固定ページ 2 – プログラミング – Home

使用PCによるアプリケーション実行時の...
 
通知
すべてクリア

[解決済] 使用PCによるアプリケーション実行時のエラー発生について

固定ページ 2 / 2

それは最低限提示すべき環境なだけで…
 それは最低限提示すべき環境なだけで…
(@それは最低限提示すべき環境なだけで…)
ゲスト
結合: 19年前
投稿: 1
 

それ以外の環境に違いがあるんでしょう?
ご自身でも書かれたように情報不足です。

再現手順なり、最低限のコードなりを提示していただかないと
我々はエスパーではありませんので…


返信引用
RAPT
 RAPT
(@RAPT)
ゲスト
結合: 22年前
投稿: 310
 

「システムコールに渡されるデータ領域が小さすぎます。」の間違いでは?


返信引用
じまお
 じまお
(@じまお)
ゲスト
結合: 20年前
投稿: 13
Topic starter  

RAPTさん、ありがとうございます。

ご指摘通りです。

エラー発生箇所と思われる部分が間違っていました。すみません。
以下のコードのEnumPortsの結果がエラーのようです。
EnumPortsがエラーを返す理由についてはまだわかりません。

BOOL Commctrl::CheckPort()
{
 /* シリアルポート検査 */
 PORT_INFO_1 pi1[sizeof(PORT_INFO_1) * ENUMPORT];
 DWORD dwNeed = 0, dwRet = 0, dw;
 int i, port_count = 0;

 if ( !EnumPorts(NULL, 1, (unsigned char *)&pi1, sizeof(pi1), &dwNeed,
&dwRet) )
 {
  ErrMsg();
  return FALSE;
 }

 for(dw = 0, i = 0; dw < dwRet; dw++)
 {
  TRACE(port Name = %s\n, pi1[dw].pName);
  if ( memcmp(pi1[dw].pName, COM, 3) == 0 )
  {
   /* delete はデストラクタにて行なうので大丈夫なはず・・・!? */
   CString *str = new CString;

   str->Format(%s, pi1[dw].pName);
   str->Delete(str->Find(:), 1);
   *(strPortName + i) = str;

   i++;
  }
 }

 iPort_num = i;

 return Open_Port(ptset.iPort_Index);
}


返信引用
kure
 kure
(@kure)
ゲスト
結合: 19年前
投稿: 48
 

> if ( !EnumPorts(NULL, 1, (unsigned char *)&pi1, sizeof(pi1), &dwNeed,
&dwRet) )
> {
>  ErrMsg();
>  return FALSE;
> }

単にdwNeedがsizeof(pi1)より大きいだけでしょ。
エラー判定するならちゃんとGetLastErrorでERROR_INSUFFICIENT_BUFFERをハンドリング
しなきゃ。

一発目で失敗してERROR_INSUFFICIENT_BUFFERが返ってきたらdwNeedバイト分領域を確保
して
もう一度EnumPortsすれば大丈夫でしょ。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

> EnumPortsがエラーを返す理由についてはまだわかりません。

MSDNより
> pcbNeeded
> プリンタポートを列挙するデータのサイズ (バイト数) を受け取る変数へのポイン
> タを指定します。cbBuf がこの値より小さいと EnumPorts は失敗しGetLastError
> 関数が ERROR_INSUFFICIENT_BUFFER を返し、pcbNeeded が指すデータは必要なバッ
> ファサイズを表します。cbBuf がこの値と等しいかこの値より大きいと、cbNeeded
> が指す変数はバッファに格納されたバイト数を表します。
とあります。

一応ここは、2段回でEnumPortsをよんだほうがよさそう。

#include <windows.h>
#include <iostream>

int main()
{
DWORD dwNeed, dwRet;
BYTE* buff;
PORT_INFO_1* pi1;

::EnumPorts( NULL, 1, NULL, 0, &dwNeed, &dwRet );
buff = new BYTE[ dwNeed ];
if ( ::EnumPorts( NULL, 1, buff, dwNeed, &dwNeed, &dwRet ) )
{
pi1 = ( PORT_INFO_1* )buff;
for ( int i = 0; i < dwRet; i++ )
{
std::cout << pi1[ i ].pName << std::endl;
}
}
delete[] buff;

return 0;
}


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

ついでに
> if ( memcmp(pi1[dw].pName, COM, 3) == 0 )

strncmpの方が最適かも。(意味合い的に)

> *(strPortName + i) = str;
これって、strPortName は CString* 型の配列でしょうか?
CStringArrayを利用すると、メモリを気にせずに扱えますよ。

>   CString *str = new CString;
>
>   str->Format(%s, pi1[dw].pName);
>   str->Delete(str->Find(:), 1);
>   *(strPortName + i) = str;

// コンストラクタで文字列を設定できる
CString str( pi1[ dw ].pName );
// : が1つしかでてこないならReplaceを使ってみるとか
str.Replace( _T( : ), _T( " ) );

// strPortNames が CStringArray型 のメンバ変数だと便利
strPortNames.Add( str );


返信引用
じまお
 じまお
(@じまお)
ゲスト
結合: 20年前
投稿: 13
Topic starter  

kureさん、Blueさん

教えて頂いた方法で修正したところ、上手くいくようになりました。

今後はもう少しエラー発生箇所をしっかり絞り込めるようにしたいと思います。

親切・丁寧なご指導ありがとうございました。


返信引用
固定ページ 2 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました