2009-12-30 38 views
1

我想從C++/CLI加載兩個程序集;程序集A依賴於程序集B,都是VB.Net項目(3.5)。我希望他們從一個字節數組中加載,所以我使用Assembly :: Load(),但是當我試圖從程序集A實例化一個類時,框架忽略了以前加載的程序集B並嘗試再次加載它,它不在搜索路徑中。程序集的「名稱」是相同的,所以我不知道它爲什麼失敗。出於測試目的,我的程序直接從編譯後的圖像加載字節,但真正的代碼將以不同的方式加載。這是我的測試代碼:從C++/CLI加載相互依賴的程序集

#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,版本= 1.0.3650.39903文化=中性公鑰=空' 或之一它的依賴關係。該系統找不到指定的文件。

當我檢查assemblyb->全名,它說,正是 'AssemblyB,版本= 1.0.3650.39903文化=中性公鑰=空'。

當然,如果我將AssemblyB.dll複製到我的測試程序的文件夾中,代碼工作得很好,但那不是我想要的。

任何想法?

(順便說一句,我的第二個步驟將是試圖讓我的C++/CLI exe將暴露AssemblyA使用類。)

+0

嗯......從我在這裏閱讀(http://stackoverflow.com/questions/416468/weird-behaviour-when-mixing-loading-of-assemblies-using-assembly-loadfrom-andass )似乎我應該實現一個ResolveHandler,但是我沒有最清楚的知道C++/CLI中AddHandler()的語法是什麼! :P –

回答

5

OK,我只是讓人看見自己。這些都在文檔中。

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

我希望有人認爲這有用。 :)

相關問題