none
VC++2005で作成したATLプログラムがVC++2010でビルドできない RRS feed

  • 質問

  • VC++2005(MFC)でCOMサーバをテストするためのクライアントアプリを作成しております。
    クライアント側で定義したインターフェースをCOMサーバに渡して、COMサーバからイベント通知
    をコールバックで受けるというものです。

    COMサーバに渡すインターフェースはクライアントで以下のように定義しており、VC++2005では
    問題なくビルドできており、動作も確認しております。

    しかし、VS2010でビルドしてみましたが、以下のエラーが発生してしまいます。
     「InternalAddRef:識別子が見つかりませんでした」
     「InternalRelease:識別子が見つかりませんでした」
    DECLARE_PROTECT_FINAL_CONSTRUCTマクロの宣言で発生しているようなのですが、原因
    は分かっておりません。
    VS2005でもVS2010でもビルド可能にしたいのですが、方法をご存知の方がいらっしゃいましたら、
    ご教授下さい。
    ===========================================================
    #define _ATL_ATTRIBUTES

    #include <atlbase.h>
    #include <atlcom.h>

    [
     object,
     uuid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"),
     dual, helpstring("ITestNotification  Interface"),
     pointer_default(unique)
    ]

    __interface ITestNotification : IDispatch
    {
     [id(1), helpstring("Method OnNotify")] HRESULT OnNotify([in] ULONG Param1, [in] ULONG Param2);
    };

    [
     coclass,
     default(ITestNotification ),
     threading(both),
     vi_progid("TestProgram.TestNotification"),
     progid("TestProgram.TestNotification.1"),
     version(1.0),
     uuid("YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY"),
     helpstring("TestNotification Class")
    ]

    class ATL_NO_VTABLE CTestNotification :
     public ITestNotification
    {
    public:
     CTestNotification()
     {
     }

     DECLARE_PROTECT_FINAL_CONSTRUCT()

     HRESULT FinalConstruct()
     {
      return S_OK;
     }

     void FinalRelease()
     {
     }

    public:
     STDMETHOD(OnNotify)(ULONG Param1, ULONG Param2);
    };

    2010年8月3日 6:44

回答

  • >変化を吸収できる手段

    残念ながら、エラーが出ている状況でそういった手段はないと考えたほうが良いです。

    Projectの設定はConvertでそれなりに変換してくれますが、

    Source Codeまでは変換してくれません。

     

    エラーが出ている状況から変更点を考察し、

    自分でSource Codeを修正する必要があります。

     

    >ビルドすることを目的

    ビルドが目的でしたら、

    エラーの通り自分でInternalAddRef/InternalRelease Methodを実装しましょう。

    そこから本件の原因調査を進めるのも良いかもしれませんね。

     

    ご参考までに、2010向けのSampleは以下にあります。

    [Walkthrough: Creating a COM Server Using a Text Editor]

      http://msdn.microsoft.com/en-us/library/2wad1c0e(v=VS.100).aspx

     

    このSampleが正しくBuildできるのであれば、

    自分のSource Codeとの相違点や、

    Projectの設定を確認してみると良いでしょう。

     

    • 回答としてマーク TSN11 2010年8月10日 11:56
    2010年8月9日 14:54

すべての返信

  • 確認です。

    1.DECLARE_PROTECT_FINAL_CONSTRUCT() Macroを記述した理由は何でしょうか?

    2.FinalConstruct/FinalReleaseは呼ばれますか?

      呼ばれる場合、

      2-1.ATL内部から呼ばれますか?

      2-2.それとも、自分で記述したCodeから意図的に呼んでいますか?

    親ClassにCComObjectRootExが存在する場合に使用されるMacroですが、

    そうでない場合、このMacroを使用する理由が記載された内容からは分かりませんでした。

     

    FinalConstruct/FinalRelease/InternalAddRef/InternalRelease Methodは、

    CComObjectRootEx/CComObjectRootBaseが持つMethodです。

    そのMacroは、特定の目的を実現するために使用し、

    子ClassでMethodを再定義します。

     

    [CComObjectRootEx クラス]

      http://msdn.microsoft.com/ja-jp/library/8hzca2fs.aspx

     

    [DECLARE_PROTECT_FINAL_CONSTRUCT]

      http://msdn.microsoft.com/ja-jp/library/97c868sh.aspx

    2010年8月8日 13:29
  • kozz様ご返答ありがとうございます。

    1.DECLARE_PROTECT_FINAL_CONSTRUCTを記述した理由
    特に明確な理由はないのですが、クライアントアプリに最低限の記述でCOMオブジェクトを定義できるように以下のサイトの一部を参考に作成しました。
     http://msdn.microsoft.com/ja-jp/library/2wad1c0e(VS.71).aspx
    また、ATLシンプルオブジェクトをウィザードで作成した場合にも本マクロが記述されているため、必要な記述だと思っておりました。

    2.FinalConstruct/FinalRelease
    インターフェースの呼び出しにはCComPtrを使っていたと思いますので、明示的に呼んでいる訳ではないと思います。
    曖昧な返答で申し訳ありませんが、現在はソースを確認できない状況ですので、実際に呼ばれているか、どこから呼ばれているかを確認出来ておりません。

    COMサーバに渡すインターフェースをクライアント側で定義する際に上記のような記述は不要なのでしょうか。

    2010年8月8日 14:48
  • 補足です。

     

    同じSourceCodeを異なる開発環境でBuildする場合、

    それぞれの開発環境に付属するATL等のライブラリ仕様が変わることがあるため、

    その変更点や影響を十分配慮した上で、SourceCodeを記述しなければなりません。

    それが難しい場合、SourceCodeの共有は避けたほうが懸命です。

     

    例えば、上記のURLと以下のURLを比較すると、

      [チュートリアル : テキスト エディタを使った COM サーバーの作成]

        http://msdn.microsoft.com/ja-jp/library/2wad1c0e(VS.80).aspx

     

    前者は以下のように記載されていますが、

      #import "vc70.tlb" no_namespace

    後者は以下のように記載されています。

      #import "vc80.tlb" no_namespace

    (あくまで、単なる一例です)

     

    テストするためのクライアントアプリを作成するのであれば、

    同一開発環境で作成したほうが良いでしょう。

    評価工程で何か不都合が発生した場合に、原因の切り分けが困難になることがあります。

     

    例えば、

    2005で作成したテストアプリでは問題が起きないが、

    2010で作成したテストアプリでは不都合が起きる場合など、

    何が原因であるか追究が難しくなることがあります。

     

    そういったことを承知済みでしたら、

    開発環境の変更による変更点や影響を明らかにしましょう。

    今回の件に限らず、それが困難だとテストアプリの信頼性自体が確保できませんよ。

    2010年8月8日 16:33
  • kozz様、ご返答ありがとうございます。

    >>同じSourceCodeを異なる開発環境でBuildする場合、
    >>それぞれの開発環境に付属するATL等のライブラリ仕様が変わることがあるため、
    >>その変更点や影響を十分配慮した上で、SourceCodeを記述しなければなりません。
    >>それが難しい場合、SourceCodeの共有は避けたほうが懸命です。

    >>テストするためのクライアントアプリを作成するのであれば、
    >>同一開発環境で作成したほうが良いでしょう。

    仰る内容は承知しているつもりですが、事情によりVS2005/VS2010でビルド可能にして動作を確認する必要があります。
    初めにテストアプリで試してみたのでテストアプリと記載しておりますが、同様なCOMサーバに対するクライアントアプリもVS2005/VS2010でビルドできるようにする必要があります。C#、VBはVS2005でもVS2010でもビルドが可能だったのですが、VC++はVS2010でビルド出来ませんでした。

    以下のURL等でVC++2010に関する影響も確認してみたのですが、ATLライブラリで関連しそうな内容が見つかりませんでした。
    http://msdn.microsoft.com/ja-jp/library/bb531344.aspx

    何らかプロジェクトの設定やソースを修正することでビルドが可能にならないかと思い、上記のような質問をさせて頂いております。

    困難なようであれば、kozz様のご指摘の通りにソースを共有せずに別途作成することも検討致します。

    2010年8月9日 6:24
  • C#、VBはVS2005でもVS2010でもビルドが可能だったのですが、VC++はVS2010でビルド出来ませんでした。

    C#、VB.NET は劇的な変化が起きていません。
    クラスライブラリの追加、言語構文の拡張はありますが、ほとんどのコードはそのまま通ります。

    C++ の世界では、MFC/ATL のヘッダー、ライブラリが変化してきていると思います。
    取り巻く環境の変化、標準 C++ との立ち位置に変遷、サポートする機能の増減など、同じレベルでは語れない変更が多いと思います。

    以下のURL等でVC++2010に関する影響も確認してみたのですが、ATLライブラリで関連しそうな内容が見つかりませんでした。
    http://msdn.microsoft.com/ja-jp/library/bb531344.aspx

    疑問を感じたのですが、なぜ 2010 の変更点だけ見ているのでしょうか?
    間の 2008 の影響はなかったのでしょうか?

    ただ、今回の問題がどの変更によるものか、そもそも変更による影響だけが問題なのかは確認していません。
    # ちなみに、属性付き ATL プロジェクトの新規作成は、ウィザードからはできなくなっているはずです。

     

    再現試験をしようかと思ったのですが、思いの外、準備に手間取りそうなのでやめました。orz


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    2010年8月9日 11:46
    モデレータ
  • Azulean様、ご返答ありがとうございます。

    C#、VB.NET は劇的な変化が起きていません。
    クラスライブラリの追加、言語構文の拡張はありますが、ほとんどのコードはそのまま通ります。

    C++ の世界では、MFC/ATL のヘッダー、ライブラリが変化してきていると思います。
    取り巻く環境の変化、標準 C++ との立ち位置に変遷、サポートする機能の増減など、同じレベルでは語れない変更が多いと思います。

    もちろん、 C#、VB.NETとC++の変化を同じレベルで考えている訳ではありません。C#、VB.NETでは対象フレームワークを指定することが出来たりしましたので、C++でも既存コードを新しい開発環境で使用するために上記のような変化を吸収できる手段があればと思い、上記の質問をさせて頂いております。

    疑問を感じたのですが、なぜ 2010 の変更点だけ見ているのでしょうか?
    間の 2008 の影響はなかったのでしょうか?

    ただ、今回の問題がどの変更によるものか、そもそも変更による影響だけが問題なのかは確認していません。
    # ちなみに、属性付き ATL プロジェクトの新規作成は、ウィザードからはできなくなっているはずです。

    説明不足で申し訳ありませんが、VC++2008に関する内容も確認しております。ただし、VS2005で作成したソースをVS2010でビルドすることを目的としておりますので、このように記載しております。

    互換性に関する記事に明記されていなくとも、ヘッダーやライブラリが変わっているようですので、それらの変更を少し調べてみます。

    2010年8月9日 13:04
  • >変化を吸収できる手段

    残念ながら、エラーが出ている状況でそういった手段はないと考えたほうが良いです。

    Projectの設定はConvertでそれなりに変換してくれますが、

    Source Codeまでは変換してくれません。

     

    エラーが出ている状況から変更点を考察し、

    自分でSource Codeを修正する必要があります。

     

    >ビルドすることを目的

    ビルドが目的でしたら、

    エラーの通り自分でInternalAddRef/InternalRelease Methodを実装しましょう。

    そこから本件の原因調査を進めるのも良いかもしれませんね。

     

    ご参考までに、2010向けのSampleは以下にあります。

    [Walkthrough: Creating a COM Server Using a Text Editor]

      http://msdn.microsoft.com/en-us/library/2wad1c0e(v=VS.100).aspx

     

    このSampleが正しくBuildできるのであれば、

    自分のSource Codeとの相違点や、

    Projectの設定を確認してみると良いでしょう。

     

    • 回答としてマーク TSN11 2010年8月10日 11:56
    2010年8月9日 14:54
  • kozz様、度々のご返答ありがとうございます。

     ビルドが目的でしたら、

    エラーの通り自分でInternalAddRef/InternalRelease Methodを実装しましょう。

    そこから本件の原因調査を進めるのも良いかもしれませんね。

    ご助言の通りに、先ずはビルド出来るようにしてから原因調査を行いたいと思います。

    ご参考までに、2010向けのSampleは以下にあります。

    [Walkthrough: Creating a COM Server Using a Text Editor]

      http://msdn.microsoft.com/en-us/library/2wad1c0e(v=VS.100).aspx

    このSampleが正しくBuildできるのであれば、

    自分のSource Codeとの相違点や、

    Projectの設定を確認してみると良いでしょう。

    コードやプロジェクト設定をSampleと比較して調査してみようと思います。

    色々とご助言を頂き、ありがとうございました。

    2010年8月10日 11:56