Pergunta

Eu quero carregar dois conjuntos de C ++/CLI; A Assembléia A depende da Assembléia B, e ambos são projetos VB.NET (3.5). Quero que eles carreguem de uma matriz de bytes, por isso uso o Assembly :: load (), mas quando tento instanciar uma classe da montagem A, a estrutura ignora o conjunto carregado anterior B e tenta carregá -lo novamente, o que falha porque porque falha porque falha porque falha porque falha porque falha porque Não está no caminho da pesquisa. O "nome" da Assembléia é o mesmo, então não sei por que falha. Para fins de teste, meu programa carrega os bytes diretamente da imagem compilada, mas o código real será carregado de maneira diferente. Este é o meu código de teste:

#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;
}

O erro é:

Não foi possível carregar arquivo ou montagem 'Assemblyb, versão = 1.0.3650.39903, cultura = neutro, publicKeyToken = nulo'ou uma de suas dependências. O sistema não pode encontrar o arquivo especificado.

Quando eu verifico o AssemblyB-> FullName, ele diz exatamente 'Assemblyb, versão = 1.0.3650.39903, cultura = neutro, publicKeyToken = nulo'.

Obviamente, se eu copiar assemblyb.dll para a pasta do meu programa de teste, o código funcionará bem, mas não é isso que eu quero.

Alguma ideia?

(A propósito, meu segundo passo será tentar fazer com que as classes usem as classes que meu exe C ++/CLI exporá.)

Foi útil?

Solução

Ok, eu apenas me envergonhei. Está tudo nos documentos.

// 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);
.
.
.

Espero que alguém ache isso útil. :)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top