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

[戻る]
じまお 2006/05/12(金) 12:59:59
はじめまして。

現在、VC++ 6.0で作成したアプリケーションを自分のPCで実行したところ、問題なく起
動できたのですが、別のPCで実行してみたところ、以下のような現象が発生します。

@メインのウィンドウが出る前にまず「システムコールに渡されるデータ領域が少なす
ぎます」というメッセージが表示される

Aメッセージを「OK」で抜けると次に「ハンドルが無効です」のメッセージが出表示さ
れる

Bメッセージを「OK」で抜けるとまた「ハンドルが無効です」が表示され、同様に
「OK」を押して抜けてもまた同じメッセージが表示され、メインウィンドウが表示され
ない

自分のPCと別PCの何かが違う為、発生しているバグ??だとは思うのですが原因が分か
りません。とりあえずOSはwindowsXPです。
このようなメッセージがPC個別に出たり出なかったりする場合、まずどこを疑ったらよ
いでしょうか?
曖昧な質問で恐縮ですが、アドバイスよろしくお願いします。

ほろー 2006/05/12(金) 13:07:47
ActiveXコントロールとか使ってない?

んー 2006/05/12(金) 13:20:10
リモートデバッグしてみたら?

じまお 2006/05/12(金) 13:21:20
ほろーさんありがとうございます。

ActiveXコントロールを使っているかどうかの確認方法はありますか?

初心者ですみません。

じまお 2006/05/12(金) 13:24:57
んーさんありがとうございます。

すみません、リモートデバッグの方法が分かりません。
「ビルド」下の「デバッガリモート接続」のことでしょうか?

じまお 2006/05/12(金) 13:35:49
ほろーさん、ActiveXの有効・無効が影響するか自分で調べてみたところ、変化無しでし
た。

ほろー 2006/05/12(金) 15:09:21
VC6だとメニューのプロジェクト→プロジェクトへ追加→
コンポーネント及びコントロールを選択してActiveXコントロールとかを
入れてませんか?っていう意味。
別のPCにはVC6がインストールされてないんじゃないですか?

Yuki 2006/05/12(金) 15:11:59
どんなプログラムを作ったのかわからないので、なんとも言いようがないのですが、
http://support.microsoft.com/default.aspx?scid=kb%3Bja%3B249721
は参考になりますか?

じまお 2006/05/12(金) 15:40:37
ほろーさん、ありがとうございます。

コンポーネント及びコントロールから確認したところ、Galleryフォルダ下に
Registered ActiveX Controlsというディレクトリがありました。

別のPCにはVC6は入っていません。

この場合、Gallery下からRegistered ActiveX Controlsを削除した方がよいということ
でしょうか??

ほろー 2006/05/12(金) 15:56:45
>>この場合、Gallery下からRegistered ActiveX Controlsを削除した方がよいということ
でしょうか??
削除したらだめですよ〜

>>別のPCにはVC6は入っていません。
ActiveXコントロールが登録されてないのかも。
ただ、「システムコールに渡されるデータ領域が少なすぎます」ってエラーは見たこと無
いから違うかもしれません。
とにかくこれだけの情報だとよくわかりませんね。
エラー箇所を絞り込んで発生箇所のコードだして質問されてはどうですか?

じまお 2006/05/12(金) 18:38:50
ほろーさん、Yukiさん、ありがとうございます。

そうですね・・・ちょっと情報が少なすぎますね。すみません。
現状、実行できるPCと出来ないPCにそれぞれVC6を入れてステップ実行してみてますの
で、詳しいエラー発生箇所が分かり次第、再度ご報告します!!

e-to 2006/05/12(金) 19:03:31
現状、実行できるPCと出来ないPCにそれぞれVC6を入れてステップ実行してみてますの
で、詳しいエラー発生箇所が分かり次第、再度ご報告します!!

えーと… 2006/05/12(金) 19:13:37
誤送信してしまいました…

>実行できるPCと出来ないPCにそれぞれVC6を入れてステップ実行してみてます
下手にインストールしちゃうと、問題によっては実行できるようになってしまって原因不
明になる可能性も…
環境はなるべくいじらずリモートデバッグされたほうがいいと思いますよ

じまお 2006/05/15(月) 10:00:42
えーと…さん、ありがとうございます。

確認してみたらNGだったPCの方にもVC6が入っていました・・・すみません。

現状、エラーの発生している箇所を調査した結果、CreateDialogIndirectでエラーにな
っていそうです。OK時は問題ないものの、NG時は例の「システムコールに渡されるデー
タ領域が少なすぎます」というメッセージが出るみたいです。
引数の値を見る限りOK時もNG時もほぼ同じようです。

とりあえず現状報告です。

じまお 2006/05/15(月) 17:51:23
追記です。

現在デバッグに使用しているPCのスペックは以下の通りです。
○2台共通
Windows XP Professional Service Pack 2
Intel Pentium M processor 1300MHz 512MB
でOKPCは
システムクロック数:595MHz
HD:30GB
でNGPCが
システムクロック数:1.29GHz
HD:40GB
です。

上記の差で、「システムコールに渡されるデータ領域が少なすぎます」というエラーは
発生するものなのでしょうか?

よろしくお願いします。

それは最低限提示すべき環境なだけで… 2006/05/15(月) 20:14:48
それ以外の環境に違いがあるんでしょう?
ご自身でも書かれたように情報不足です。

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

RAPT 2006/05/16(火) 04:20:46
「システムコールに渡されるデータ領域が小さすぎます。」の間違いでは?

じまお 2006/05/16(火) 09:53:30
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 2006/05/16(火) 10:03:53
> 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 2006/05/16(火) 10:09:18
> 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 2006/05/16(火) 10:23:51
ついでに
> 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 );

じまお 2006/05/16(火) 11:59:23
[[解決]]
kureさん、Blueさん

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

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

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

古いスレッドには追加発言できません。