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

时间:2008-08-22 13:23:16

标签: c# .net 64-bit clr x86-64

我遇到的问题与描述here(加载程序集及其依赖项)类似,但略有不同。

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

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

更具体地说,这里适用的上述问题的建议答案也是如此(即创建一个ResolveEvent处理程序)?

3 个答案:

答案 0 :(得分:8)

我终于得到了一个似乎有用的答案。

编译32& 64位版本 - 管理和安装unmanaged - 进入单独的文件夹。然后让.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);

  }

你最终有2个exes - 你的普通应用程序和第二个切换应用程序,它选择加载哪些位。 注意 - 我自己也不能相信这个细节。我的一位同事怀疑我的初始指针。如果他注册StackOverflow,我会给他答案

答案 1 :(得分:3)

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

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

答案 2 :(得分:1)

我前段时间遇到过类似的情况。我使用的工具包在64位环境中表现不佳,我无法找到动态强制程序集绑定为32位的方法。

可以强制程序集在32位模式下工作,但这需要修补CLR标头(在框架中有一个工具可以执行此操作),如果程序集具有强名称,则不起作用进行。

我担心你需要为32位和64位平台构建和发布两组二进制文件。