1

以下のように C++/CLI クラスを宣言しました

namespace testcominterface {

  [ComVisible(true)]
  [Guid("FFCA805F-8DAB-4AF8-A7B7-B488136E8177")]
  public interface class ITestInterface
  {
      public :
          void TestMethod();
  };


  [ComVisible(true)]
  [Guid("E65F4772-54B5-4105-83E5-DCED24ABC815")]
  [ClassInterface(ClassInterfaceType::AutoDual)]
  [ComDefaultInterface(ITestInterface::typeid)]       
  public ref class testCoClass : ITestInterface
  {
      public:
          virtual void TestMethod()
                {

                    Console::WriteLine("testCoClass::TestMethod : Test method");

                }
  };
 }

そして、ネイティブ C++ COM (TLB ファイルを #import して CoCreateInstance を使用) を介して "testCoClass" を作成したいのですが、常に "Class Not Registered" というエラーが発生します。「Regasm.exe」を使用してアセンブリを登録すると正常に動作しますが、アセンブリを登録したくありません。

このブログ投稿の手順に従いましたhttp://blogs.msdn.com/b/cheller/archive/2006/08/24/how-to-embed-a-manifest-in-an-assembly-let-me -count-the-ways.aspxを使用してマニフェストをアセンブリに埋め込みましたが、機能しませんでした。(このメソッドは常に C# アセンブリで機能しますが、これは C++/CLI アセンブリであることに注意してください。

提案をいただければ幸いです。

4

1 に答える 1

2

クライアント プログラムが DLL を要求したときに COM が DLL を見つけることができるように、COM サーバーを登録する必要があります。<clrClass>技術的には、マネージド コードで記述された COM サーバーに必要な、reg-free COM エントリを含むマニフェストをクライアント プログラムに与えることで回避できます。重要な点は、このマニフェストはサーバーではなくクライアントに埋め込む必要があるということです。COM サーバーが適切に動作するようになるまでは、まだそこに移動しないでください。

よくある間違いの 1 つは、Regasm.exe で /codebase オプションを使用するのを忘れることです。それがなければ、アセンブリに厳密な名前を付けて GAC に入れる必要があります。これは、開発マシンでやりたいことではありません。もう 1 つのよくある間違いは、間違ったバージョンの Regasm.exe を使用することです。64 ビット マシンではビット数に注意する必要があります。VS2010 を使用して GAC を使用する場合は、適切なものを選択してください。.NET 4 では、GAC の場所が異なります。

使用する属性を改善する必要があります。適切な COM サーバーは、インターフェイスのみを公開し、実装を隠します。インターフェイス宣言では [InterfaceType(ComInterfaceType::InterfaceIsDual)] を使用し、クラスでは [ClassInterface(ClassInterfaceType::None)] を使用します。[ComDefaultInterface] も不要になり、mscorlib.tlb へのタイプ ライブラリの依存関係がなくなります。

それでも問題が解決しない場合は、SysInternals の ProcMon ユーティリティを使用して、クライアントがサーバーを検索したレジストリ内の正確な場所を表示し、サーバーが使用する実際のレジストリの場所と比較できます。

于 2012-04-01T14:57:53.287 に答える