• ベストアンサー

VC++のCOMのデバッグ方法について

VC++でつくられたCOMをデバッガを使ってデバッグしたいのですが どのようにすればいいのか、よい手段がわからず困っています。 いま担当しているプログラムの作りとしては、 2つの実行可能形式ファイル(AAA.exeとBBB.exe)があって、 AAA.exeは、 単独で動かした場合は自分のクラスをレジストリ登録/解除するプログラムで それ以外にもいくつかの関数(後述のfunCCC関数やログ出力関数)を実装しています。 BBB.exeは、CoCreateInstance関数を使用してAAA.exe内のクラスのオブジェクトを作成して その中で定義されている関数(funcCCC)にアクセスしています。 AAA.exeを実行してCOMがレジストリ登録されていることは レジストリエディタで確認できていて、 また、BBB.exe内でCoCreateInstance関数が成功していることも、 funcCCCが実行されて正常で結果が戻ってきていることもプログラムの実行結果からわかります。 この状態で BBB.exeからfuncCCCをコールしたときに AAA.exeのfuncCCCにステップインしてデバッグしたいのですが このようなことは、たとえばVisualStudio(2003)のデバッグ機能でできるのでしょうか。 デバッグしたい理由としては、AAA.exeの単体テストを行うためと、 あと、AAA.exe内のログ出力関数が AAA.exeを単独で起動したとき、つまり 自分のクラスをレジストリ登録するときは正常にログ出力されているのですが BBB.exeからfuncCCCを実行したときは、 funcCCC内で同じログ出力関数をコールしているのにログが出力されていないので デバッガを使って内部でどういう状態になっているのかを確認したいのです。 ログが出力されないので MessageBox関数を埋め込んでトレースや変数の内容を確認しているのですが その結果ではAAA.exeを単独で実行したときと同じように ログ出力関数がコールされているように見えます。 また DebugBreak関数を使う方法というのを見かけたので funcCCC内でDebugBreak()を実装してみたのですが その場合は、DebugBreakのところでプログラム(BBB.exe)が終了してしまいます。 COMについて認識違いがあればご容赦下さい。 よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • gentoo314
  • ベストアンサー率41% (15/36)
回答No.3

気になったので、VS2003にて、ATL-EXEタイプのCOMを作ってテストしたところうまくいきました。 AAA.exe が終了していることを確認。走っていればタスクマネージャで強制終了してください。 AAA.exe のfuncCCCにブレークポイントを張っておいて、デバッグ起動。タスクマネージャにて AAA.exe が走っていることを確認。 BBB.exe をデバッグ起動。BBB.exe から、funcCCC を呼び出すと、ブレークポイントで止まります。 AAA.exe をCOM経由で起動させずに、VS上から起動しておくのがポイントです。

hvorfor
質問者

お礼

回答ありがとうございました。 この方法を試してみて、 BBB.exeからfuncCCCへ進んでいけることを確認しました。 COM経由でない方法でデバッグすればよかったんですね。 期待していたとおりの動きで、本当にありがとうございました。 あと、自分でも投稿後にいろいろ試していたところ、 オプションのデバッグの設定でRPCデバッグのところにチェックを入れると この方法でもBBB.exeからfuncCCCへステップインできました。 補足ということで載せておきます。

その他の回答 (2)

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

AAA.exeのプロジェクト(ソリューション)はあるのでしょうか? AAAプロジェクトのプロパティまたは設定で 実行開始ファイルに BBB.EXEを設定 funcCCCの冒頭にブレークポイントを設定 F5でデバッグ実行 BBB.EXEの操作でfunCCCが呼ばれた時点でIDEがアクティブになると思います AAA.EXEがデバッグビルドである前提ですが ・・・

hvorfor
質問者

補足

回答ありがとうございます。 AAA.exe、BBB.exeともにプロジェクトが存在していて 両方ともデバッグモードでビルドしています。 レジストリ登録するとき(AAA.exeを単独で起動するとき)も デバッグビルドの資産で行っています。 ご回答いただいている方法を試してみたのですが、 funcCCCのところで止まることはなく そのままプログラムが続行してしまいました。 funcCCC内の処理は正常に実行されているようです。 BBB.exe内のfuncCCCに入る直前にブレークポイントを張っても ステップインできずに処理が続いてしまいます。 通常のDLLのデバッグだと 回答していただいた方法でデバッグできることを確認しているのですが レジストリ登録されたものを呼び出す場合は この方法以外に何か配慮が必要なのかと思っています。

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.1

>AAA.exeを単独で起動したとき、つまり >自分のクラスをレジストリ登録するときは正常にログ出力されているのですが >BBB.exeからfuncCCCを実行したときは、 >funcCCC内で同じログ出力関数をコールしているのにログが出力されていないので ログファイルは、誰が、どのタイミングでオープン、クローズしていますか? 前者と後者では「実行しているプロセス」が異なるので、ログファイルのアクセス権やオープンクローズのタイミングを考えねばなりません。 「ログファイルへのアクセス権がAAA.exeにしか無い」なら、後者の場合にはログは出力出来ません。

hvorfor
質問者

お礼

回答ありがとうございます。 ログファイルのオープン/クローズは ログ出力関数内の出力する直前・直後で行っています。 ただ、オープン/クローズにエラー処理が入っていなくて 投稿後にエラーメッセージを取得する処理を入れて確認してみたところ ログファイルのパスの指定がおかしくなっていました・・・ 既存のプログラムに改修を入れているのですが 実行ドライブがCからDに変わったものの ファイルパスはドライブ指定を省略していたために 単独で起動したときはDドライブ配下のパスに、 COMから呼び出したときはCドライブ配下のパスになっていたようです。 投稿する前に確認が足りなくて申し訳なかったです。

関連するQ&A

  • Visaul Studioでのデバッグ(COMコンポーネントのデバッグ方法)

    お世話になります。 今、VC++でATLのCOMプログラムをしていますが、 デバッグ方法がわかりません。コンパイルして、実行は、.htmファイルを開くため、C言語などのようにprintf()などで値を見たり、デバッガなどが起動してもブレイクポイントが?になります。 そこで少し調べたところ、MSDNに記載されていました。 http://msdn2.microsoft.com/ja-jp/library/ya4xb00s(VS.80).aspx Visual StudioでのCOMコンポーネントのデバッグ設定方法についてです。 の手順3.eのCOMコンポーネントノードとはどれをさすのでしょうか? COM+アプリケーションふぉるだを開くと COM+ Explorer COM+ QC Dead LetterQueue Listener COM+ Utilities などがあります。 よろしくお願いいたします。

  • VBがデバッグ時落ちてしまう

    VC6.0でDLLを作成し、VB6.0で呼び出すプログラムを作成しています。 DLLの内容はWindowハンドルを引数にしてそのハンドルを持つWindow上にListboxを作成するというようなものです。(もともとC言語用のDLLだったものをVBで使いまわしています) このプログラムをデバッグ実行し、デバッガ上で停止[実行->終了]とすると、VB6.exeがアプリケーションエラーで落ちてしまいます。(DLLの関数を呼ばない限り大丈夫です) デバッグ実行でも普通に終了(アプリケーションでの終了)であれば正常に終了してくれます。 このままですと、実行時エラーで止まる度にVB6.exeが落ちてしまい非常に不便です。 このような現象で困った方いませんか? 解決策がありましたら教えてください。

  • 子プロセスのデバッグ方法について

    VisualStudio2008のVCでデバッグをしています。 Win32のCreateProcess関数で"自分自身"のEXEファイルを実行すると、新プロセスが起動するのですがデバッグができません。 CreateProcessの呼び出し側プロセスと、同じプログラムである新プロセスを同時にデバッグすることはできないものでしょうか。

  • 「Just-In-Time デバッグ」 の表示が消えない

    過去ログに類似があるのですが、ド素人目にはガッツリ当て嵌まるのが見つからず、質問させていただきます。 Yahooメッセンジャーが起動するのと同時に 「Just-In-Time デバッグ」という表示が出てきました。そこには 「デバッガを選択してください  可能なデバッガ(P)  ・新しいスタンス Microsoft Script Editor」 とあります。 その下に、チェックボックスにチェックの入っている 「現在選択されているデバッガを規定のデバッガに設定します(D)」 という表示と、 「選択したデバッガを使ってデバッグしますか?」 「はい」「いいえ」 の選択肢があります。 「いいえ」で消しても、1,2秒で再び同じ画面が勝手に出てくるので、 「はい」をクリックして見ると…。 「リモート プロシージャ コールにステップイン」 ・プロセス(P):  [2744] D:\Program Files\Yahoo!J\Messenger\YahooMessenger.exe」  ・デバッグするプログラムの種類を選択(C)」  「レ」型のチェックマークの入った「Script」 ・以下のプログラムをデバッグします  「スクリプト」 という表示が出ます。OKを選択すると、 「その他のファイル」という画面と同時に、 「Microsoft Visual Studioデバッガ」という小窓と、「実装されていません」という文字が出ます。 やむなく「中断」を押し、デバッグを中止すると、勝手に出てくる最初の小窓に逆戻りします。 エンドレスです…(ToT)/~~~ そして、Yahooメッセンジャーが(応答なし)という表示になっていて使えません。 どうすればいいんでしょうか…。 お分かりになる方、いらっしゃいましたら助けてください。 何か足りない説明がありましたら補足します。 よろしくお願い致します。

  • 緊急です。デバッグについて…。素人です。

    自社HPをみようとすると、 今まで見れていたのですが何かを触ってしまったのか ある日みれなくなっていました。 表示されるとおりに進んでいっても解決できません。 表示されるコメントを下記に書いておきました。 不足がありましたら、ご指摘ください。 急いでいます!アドバイスお願いします。 HPをブックマークより開くと 「ランタイムエラーが発生しました。デバッグしますか? 行:11 エラー:オブジェクトがありません」 ↓ “はい”を選択。 ↓ 「デバッガを選択してください。」 このとき“可能なデバッガ”に “新しいインスタンスMicrosoht Script Editor”が表示されているのでそれが選択されています。 「選択したデバッガを使ってデバッグしますか?」 となっているので“はい”を選択。 ↓ “リモートプロシージャコールにステップイン”という タイトルの画面が出てきて “デバッグするプログラムの種類”に“Script”が選択されていて “以下のプログラムをデバッグします”に“スクリプト”が 選択されています。 ↓ “OK”をクリックすると 「Microsoft JScript実行時エラー:オブジェクトがありません」 となってしまいます。 その後“接続”をやっても上記のメッセージが出ます。 どうすればいいのでしょうか? 素人なのですみませんが細かく教えてください。

  • CreateFile が ERROR_PATH_NOT_FOUND のエラーになる

    VC++を使っています。OSは Windows2000 です。 CreateFile で指定するファイル名をフルパスで指定し、EXEを同じ ディレクトリに置いて実行したところエラーとなり、詳細コードが ERROR_PATH_NOT_FOUND でした。 プログラムは以下のようになっています。 #define AAA "c:winnt\\system32\\AAA.log" hOpen = CreateFile( AAA, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 上記プログラムの AAA.exe を system32下に置いて実行すると、 パスが不正だと怒られてしまいます。。。 AAA.exe を別ディレクトリで実行すると、sysytem32下にちゃんと ファイルが作成されます。 AAA.exe を CreateProcess する BBB.exe を造って試しましたが、 やはり BBB.exe が system32下にあると駄目でした。 どうやらカレントディレクトリが同じだと駄目みたいです。 「"AAA.log"」とせずにフルパスとしているのは以下の理由のためです。 ・ファイルは必ず system32下に作成したい。 ・AAA.exe は必ず system32下にある。 しかし、BBB.exe が必ず system32下にあるとは限らないため、 「"AAA.log"」とした場合、BBB.exe を実行したディレクトリに 作成されてしまう。 CreateFile には今回のような制限があるのでしょうか??? #ヘルプを見る限り、書いてないです。。。

  • 【C++】外部プログラムを呼んで、そのプログラムから値を取得したい

    【C++】外部プログラムを呼んで、そのプログラムから値を取得したい 現在、windowsXp pro でVC2008コンパイラで 普通のC++のプログラムを組んでいます。 コマンドプロンプト上で、C++プログラム(aaa.exe)を実行し、 そのaaa.exeから別のC++プログラム(bbb.exe)に引数を渡して 実行しようと思います。 このとき、bbb.exeで処理したデータ(xxx)をaaa.exeに返したい のですが、どういう方法があるのでしょうか。 (例えば、aaa.exeからbbb.exeに4つのint型引数k,l,m,nを渡し、  bbb.exe内で、k+l, m-nを計算して、2つの計算結果を返したい  と思います。) (aaa.exe、bbb.exe間のデータ渡しにファイルを使わないという  条件でお願いします。) サンプルプログラムを提示して頂きたくお願いします。

  • VC++のプロジェクト指定

    VC++でほぼ始めて”EXE”を開発するのですが、[新規作成]でどのプロジェクトを指定すればいいかわかりません。 つまり、「MFC AppWizard(exe)」と「Win32Application」と「Win32ConsoleApplication」の使い分けがわかりません。 ちなみに、現在、あるAPからCALLされるEXEを作ろうとしています。 このEXEの機能は、レジストリからある情報を読み込み、その内容をINIファイルに出力し、読み込んだレジストリ情報で指定されているEXEにパラメータとしてこのINIファイルを設定し、実行させるものです。 宜しくお願いします。

  • VC6.0のデバッグで1つ以上のブレイクポイントが

    VCのサンプルプログラムをデバッグしようとしています。 デバッグ開始を実行すると、exeにデバッグ情報がありません。と表示され、 その後、ひとつ以上のブレイクポイントが設定できませんでした。と表示されます。 プロジェクトの設定でWin32 DEBUGを設定 ビルドメニューのアクティブな構成もWin32 Debug を選択していて、リビルド、コンパイルしています。 別のプロジェクトだと、うまくいくのですが・・・ ブレイクポイントの設定位置も問題ないかと思うのですが、 どなたか、お心当たりございましたら、よろしくお願いします。

  • c++,ある関数のクラスから別のクラスの関数を呼ぶ

    c++で、あるクラスのメンバ関数から、別のクラスのメンバ関すを呼びたいのですが、どのようにしたらできますか? 例えば、以下のような単純なコードを考えています。やりたいことは、Aのメンバ関数であるaaa()からBのクラスであるbbb()を呼びたいと思っています。その理由を少し説明します。ここでは、Aというクラスとmain関数はオープンソースコードを例えています。できるだけ、元のオープンソースコードを書き換えずに新たな機能を拡張したいと思っています。そこで、Bというクラスを使って、元のオープンソースコードに機能を拡張しようとしています。このような理由なので、bbb()という関数はaaa()という関数から呼びたいです。メイン関数には何も書き加えないのがベストです。 現状では、実行すると「this is aaa」という出力しか出ません。ここに「this is bbb」の出力を加えたいです。クラスAとBにある程度コマンドを追加して、解決できないでしょうか。 #include <iostream> using namespace std; //------------------------------------------------------ class A{ public: void aaa(); virtual void bbb(){} }; //------------------------------------------------------ //------------------------------------------------------ class B : public A{ public: void bbb(); }; //------------------------------------------------------ //------------------------------------------------------ void A::aaa() { cout << "this is aaa \n"; bbb(); } //------------------------------------------------------ //------------------------------------------------------ void B::bbb() { cout << "this is bbb \n"; } //------------------------------------------------------ //------------------------------------------------------ int main() { A a; a.aaa(); return 0; } //------------------------------------------------------

専門家に質問してみよう