none
DLLの呼出しでキャスト例外 RRS feed

  • 質問

  •  

    はじめまして。

    私が今現在DLLをAssembly::LoadFromで読込みして実行するプログラムを作成しております。

    内容は以下の2種(本体=dllload.cpp、DLL=testdll.cpp)で、実際のものを簡略化しました。

    これを実行すると, 本体の12行目「IeaAccess^ iea = safe_cast...」で「型'xBrkIf.eaAccessのオブジェクトを型'xBrkIf.IeaAccess'にキャストできません」という例外が発生します。

    使用開発環境はVisual Studio 2008のVisual C++, .NET Framework 3.5です。

    どのようにすれば例外が解消できるかご指導いただけたら幸いです。

    宜しくお願い致します。

     

    ----------[dllload.cpp]----------------------

    #include "testdll.cpp"

    using namespace System;
    using namespace System::Reflection;
    using namespace xBrkIf;

    void main(void)
    {
     try
     {
      Assembly^ a = Assembly::LoadFrom("DLLのパスが入る");
      Object^ obj = a->CreateInstance("xBrkIf.eaAccess");
      IeaAccess^ iea = safe_cast<IeaAccess^>(obj);
      iea->message("Hello World.");
     }

     catch (Exception^ ee)
        {
      Console::WriteLine(ee->Message);
     }
    }

    ----------[testdll.cpp]----------------------

    using namespace System;
    namespace xBrkIf
    {
     public interface class IeaAccess
     {
     public:
      void message(String^ mes);
     };
     public ref class eaAccess : public IeaAccess
     {
     public:
      virtual void message(String^ mes)
      {
       Console::WriteLine("{0}", mes);
      }
     };
    }
    2008年5月14日 16:47

回答

  • 普通、cpp ファイルを include することはしません。

    cpp ファイルを include したため、dllload.exe と testdll.dll の両方に IeaAccess インターフェイスおよび eaAccess クラスが作られています。

    .NET の型システムは型の同一性をアセンブリの違いも含めて判断しますので、dllload.exe にある IeaAccess インターフェイスと testdll.dll にある IeaAccess インターフェイスは別物です。たまたま名前空間および型名が同じになっていますが。

    testdll.dll の eaAccess は testdll.dll のIeaAccess を実装しますが当然ながら dllload.exe の IeaAccess は実装していないのでキャストはできません。

    一般的には、dllload.exe および testdll.dll の両方から第三の dll を参照させ、その第三の dll に IeaAccess を定義します。

    2008年5月14日 21:24

すべての返信

  • 普通、cpp ファイルを include することはしません。

    cpp ファイルを include したため、dllload.exe と testdll.dll の両方に IeaAccess インターフェイスおよび eaAccess クラスが作られています。

    .NET の型システムは型の同一性をアセンブリの違いも含めて判断しますので、dllload.exe にある IeaAccess インターフェイスと testdll.dll にある IeaAccess インターフェイスは別物です。たまたま名前空間および型名が同じになっていますが。

    testdll.dll の eaAccess は testdll.dll のIeaAccess を実装しますが当然ながら dllload.exe の IeaAccess は実装していないのでキャストはできません。

    一般的には、dllload.exe および testdll.dll の両方から第三の dll を参照させ、その第三の dll に IeaAccess を定義します。

    2008年5月14日 21:24
  • 早速のご返答ありがとうございます。
    testdll.cppの宣言をtestdll.hに移し, dllload.cppの#includeを削除してから, 先に生成されたtestdll.dllを
    dllload.cppの参照に追加したら正常に動作しました。
    ありがとうございました。

    2008年5月15日 21:27
  • あの、testdll.dll 自体を参照に追加しちゃったら、わざわざ Assembly::LoadFrom するまでもなく普通に gcnew できるんですけど……。
    2008年5月16日 0:26
  • こんにちは! 中川俊輔です。

     

    Hongliangさん、回答ありがとうございます。

     

    ko林さん、フォーラムのご利用ありがとうございます。

    有用な情報と思われたため、Hongliangさんの回答へ回答済みチェックをつけさせていただきました。

    回答済みチェックが付くことにより、有用な情報を探している方が情報を見つけやすくなります。


    有用な情報と思われる回答があった場合は、なるべく回答済みボタンを押してチェックを付けてください。

    ko林さんはチェックを解除することもできますので、ご確認ください。

     

    それでは!

     

    2008年6月17日 7:59