如何在运行时后期绑定32位/64位库

18

我遇到了一个类似的问题,但略有不同,详细描述请参见这里(加载程序集及其依赖项)。

我们有一个用于3D渲染的C++ DLL,这是我们销售给客户的产品。对于.NET用户,我们将在其周围包装一个CLR。C++ DLL可以构建为32位和64位版本,但是我认为这意味着我们需要有两个CLR包装器,因为CLR绑定到特定的DLL?

现在假设我们的客户有一个.NET应用程序,可以是32位或64位版本,并且它是纯.NET应用程序,它会从一组程序集中让CLR自己解决。问题是,应用程序代码如何在运行时动态选择我们的32位和64位CLR / DLL组合?

更具体地说,先前提到的问题的建议答案是否也适用于此处(即创建一个ResolveEvent处理程序)?

3个回答

9
我终于找到了一个似乎有效的答案。
将32位和64位版本的托管和非托管代码编译到不同的文件夹中,然后让.NET应用程序在运行时选择要从哪个目录加载程序集。
使用ResolveEvent的问题在于只有在未找到程序集时才会调用它,因此很容易意外地得到32位版本。相反,我们可以使用第二个AppDomain对象,在其中更改ApplicationBase属性以指向正确的文件夹。这样,你的代码看起来就像这样:
static void Main(String[] argv)
  {
     // Create a new AppDomain, but with the base directory set to either the 32-bit or 64-bit
     // sub-directories.

     AppDomainSetup objADS = new AppDomainSetup();

     System.String assemblyDir = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
     switch (System.IntPtr.Size)
     {
        case (4): assemblyDir += "\\win32\\";
           break;
        case (8): assemblyDir += "\\x64\\";
           break;
     }

     objADS.ApplicationBase = assemblyDir;

     // We set the PrivateBinPath to the application directory, so that we can still
     // load the platform neutral assemblies from the app directory.
     objADS.PrivateBinPath = System.IO.Path.GetDirectoryName(Application.ExecutablePath);

     AppDomain objAD = AppDomain.CreateDomain("", null, objADS);
     if (argv.Length > 0)
        objAD.ExecuteAssembly(argv[0]);
     else
        objAD.ExecuteAssembly("MyApplication.exe");

     AppDomain.Unload(objAD);

  }

你最终会得到两个应用程序 - 一个正常的应用程序和一个第二个切换应用程序,它选择要加载的位。 注意 - 我不能为此自己的细节负责。我的一位同事在我的初始指示下找出了这一点。如果他注册StackOverflow,我将把答案分配给他。

3

大约一年前,我能够做到这一点,但现在我不记得所有的细节了。基本上,您可以使用IntPtr.Size来确定要加载哪个DLL,然后通过p/Invoke执行实际的LoadLibrary。此时,您已经将模块加载到内存中,应该能够从其中调用函数——相同的模块名称不应再次被重新加载。

我认为,在我的应用程序中,我实际上是让C++ DLL将自己注册为COM服务器,然后通过生成的.NET包装器访问其功能——所以我不知道是否曾直接测试过p/Invoke。


1

我曾经遇到过一个类似的情况。我使用的工具包在64位环境下表现不佳,而我无法找到一种动态强制这些程序集以32位绑定的方法。

强制你的程序集以32位模式工作是可能的,但这需要对CLR头进行打补丁(框架中有一个工具可以实现),如果你的程序集已经签名,则此方法将行不通。

恐怕你需要为32位和64位平台构建并发布两组二进制文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接