2

C ++/CLIから2つのアセンブリをロードしたい。アセンブリAはアセンブリBに依存しており、どちらもVB.Netプロジェクト(3.5)です。バイト配列からロードしたいので、Assembly :: Load()を使用しますが、アセンブリAからクラスをインスタンス化しようとすると、フレームワークは以前にロードされたアセンブリBを無視して再度ロードしようとしますが、これは失敗します。検索パスにはありません。アセンブリの「名前」は同じなので、なぜ失敗するのかわかりません。テストの目的で、私のプログラムはコンパイルされたイメージから直接バイトをロードしますが、実際のコードは別の方法でロードされます。これは私のテストコードです:

#include "stdafx.h"

using namespace System;
using namespace System::Windows::Forms;
using namespace System::IO;
using namespace System::Reflection;

[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
    array<unsigned char>^   bytes;
    FileStream^     f;

    f = gcnew FileStream(L"c:\\...\\AssemblyB.dll", FileMode::Open);
    bytes = gcnew array<unsigned char>((int)f->Length);
    f->Read( bytes, 0, (int) f->Length );
    f->Close();
    f = nullptr;
    Assembly^   assemblyb = Assembly::Load(bytes);

    f = gcnew FileStream(L"c:\\...\\AssemblyA.dll", FileMode::Open);
    bytes = gcnew array<unsigned char>((int)f->Length);
    f->Read( bytes, 0, (int) f->Length );
    f->Close();
    f = nullptr;
    Assembly^   assemblya = Assembly::Load(bytes);

    bytes = nullptr;

    // Here I get the file not found exception!
    Object^     mf = assemblya->CreateInstance(L"AssemblyA.MainForm");

    // This line is not reached unless I copy assemblyb.dll to my app's folder:
    mf->GetType()->InvokeMember(L"ShowDialog",BindingFlags::Default | BindingFlags::InvokeMethod,
                                mf->GetType()->DefaultBinder, mf, nullptr );

    return 0;
}

エラーは次のとおりです。

ファイルまたはアセンブリを読み込めませんでした' AssemblyB、Version = 1.0.3650.39903、Culture = neutral、PublicKeyToken=null 'またはその依存関係の1つ。システムは、指定されたファイルを見つけることができません。

assemblyb-> FullNameを確認すると、正確に「AssemblyB、Version = 1.0.3650.39903、Culture = neutral、PublicKeyToken=null」と表示されます。

もちろん、AssemblyB.dllをテストプログラムのフォルダーにコピーすると、コードは問題なく機能しますが、それは私が望んでいることではありません。

何か案は?

(ちなみに、私の2番目のステップは、AssemblyAにC ++ / CLI exeが公開するクラスを使用させることです。)

4

1 に答える 1

9

わかりました、私は自分自身を恥ずかしく思いました。それはすべてドキュメントにあります。

// This class is just for holding a managed static variable for assemblyB
ref class Resolver {
public:
    static  Assembly^   assemblyB;
};

// This is the delegate for resolving assemblies
Assembly^ ResolveHandler(Object^ Sender, ResolveEventArgs^ args)
{
    // Warning: this should check the args for the assembly name!
    return Resolver::assemblyB;
}
.
.
.
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
    // Set up the handler for the AssemblyResolve event
    AppDomain::CurrentDomain->AssemblyResolve += gcnew ResolveEventHandler( ResolveHandler );
.
.
.
    // Load assemblyb into the static variable available to the resolver delegate
    Resolver::assemblyb = Assembly::Load(bytes);
.
.
.

誰かがこれが役立つことを願っています。:)

于 2009-12-30T02:39:51.627 に答える