0

http://support.microsoft.com/kb/837908の方法3に従って、C#でアセンブリを動的にロードしています。ただし、コードが機能していません。コードの次のセクションでは、欠落しているアセンブリの名前がアプリケーションによって参照されているアセンブリの1つである場合にのみ、作成者は欠落しているアセンブリをロードします。

これをデバッグで実行すると、関数が呼び出されますが、欠落しているアセンブリは参照されているアセンブリのいずれにも含まれていないため、私の場合は設定されていません。なぜこれが起こっているのか、何か考えはありますか?そのDLLがC#なのかネイティブC++なのかわかりません。これは、C ++ dllをこの方法でロードできないためでしょうか?では、なぜこの関数が欠落しているC++アセンブリに対して呼び出されるのでしょうか。説明をいただければ幸いです。これがC#から参照されるC ++アセンブリで機能しない場合、代替手段は何ですか?

private Assembly MyResolveEventHandler(object sender,ResolveEventArgs args)
{
    //This handler is called only when the common language runtime tries to bind to the assembly and fails.

    //Retrieve the list of referenced assemblies in an array of AssemblyName.
    Assembly MyAssembly,objExecutingAssemblies;
    string strTempAssmbPath="";

    objExecutingAssemblies=Assembly.GetExecutingAssembly();
    AssemblyName [] arrReferencedAssmbNames=objExecutingAssemblies.GetReferencedAssemblies();

    //Loop through the array of referenced assembly names.
    foreach(AssemblyName strAssmbName in arrReferencedAssmbNames)
    {
        //Check for the assembly names that have raised the "AssemblyResolve" event.
        if(strAssmbName.FullName.Substring(0, strAssmbName.FullName.IndexOf(","))==args.Name.Substring(0, args.Name.IndexOf(",")))
        {
            //Build the path of the assembly from where it has to be loaded.                
            strTempAssmbPath="C:\\Myassemblies\\"+args.Name.Substring(0,args.Name.IndexOf(","))+".dll";
            break;
        }

    }
    //Load the assembly from the specified path.                    
    MyAssembly = Assembly.LoadFrom(strTempAssmbPath);                   

    //Return the loaded assembly.
    return MyAssembly;          
}
4

1 に答える 1

1

「アセンブリ」という用語は、DLLだけを意味するものではありません。これは、.NETで作成されたDLLを意味します。これは「マネージコード」とも呼ばれ、メモリの管理に従来のC++ヒープではなく.NETガベージコレクターを使用することを大まかに意味します。(単純化しています。マネージドコードとアンマネージドコードを組み合わせて使用​​しているにもかかわらず、この方法で解決される「混合モードアセンブリ」もあります。「マネージド」とは、単なるメモリ管理以上のものを意味します。)

参照するアセンブリがC++/ CLIで記述されているか、C#で記述されているかは関係ありません。C ++ /CLIはC++と混同されることがよくありますが、実際には、管理された環境を利用するための追加機能を備えた別の言語です。スイッチを使用してC++のようなものをコンパイルする場合/clr、それはC++ではなくC++/CLIです。

あなたが理解する必要がある参照されたKB記事で3つの落とし穴があります。

  1. この記事の「方法3」では、間接的に参照されるアセンブリは考慮されていません。つまり、メインアセンブリから参照されるアセンブリから参照されるアセンブリです。これはおそらく今あなたを噛んでいます。

  2. この記事では、ハンドラーを登録するメソッドの本体で行うことをできるだけ少なくすることが重要であるとは述べていません。そうしないと、ハンドラーが登録される前に、ジッターによって一部のアセンブリが解決されます。同じ方法での登録。これは、JITコンパイルが実行に先行するためです。

  3. C ++ / CLIコードを扱う場合、前者がリンクしているアンマネージC++DLLもロードする必要がある可能性があります。これは、従来のWindows DLL検索順序を使用して、リゾルバーの外部で実行されます。ただし、特定のDLLに対してハンドラーが入力されている場合は、これは問題ではありません。.NETとは関係のない通常の種類のCまたはC++DLLは、ハンドラーにまったく表示されません。

于 2012-10-28T21:46:56.927 に答える