如何在运行时延迟绑定 32 位/64 位库 [英] How to late bind 32bit/64 bit libs at runtime

查看:18
本文介绍了如何在运行时延迟绑定 32 位/64 位库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个类似于此处描述的问题,但略有不同.a>(加载程序集及其依赖项).

I've got a problem similar to,but subtly different from, that described here (Loading assemblies and their dependencies).

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

I have a C++ DLL for 3D rendering that is what we sell to customers. For .NET users we will have a CLR wrapper around it. The C++ DLL can be built in both 32 and 64bit versions, but I think this means we need to have two CLR wrappers since the CLR binds to a specific DLL?

现在假设我们的客户有一个 .NET 应用程序,它可以是 32 位或 64 位,并且它是一个纯 .NET 应用程序,它让 CLR 从一组程序集计算出来.问题是应用代码如何在运行时在 32 位和 64 位 CLR/DLL 组合之间动态选择?

Say now our customer has a .NET app that can be either 32 or 64bit, and that it being a pure .NET app it leaves the CLR to work it out from a single set of assemblies. The question is how can the app code dynamically choose between our 32 and 64bit CLR/DLL combinations at run-time?

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

Even more specifically, is the suggested answer to the aforementioned question applicable here too (i.e. create a ResolveEvent handler)?

推荐答案

我终于有了一个看起来可行的答案.

I finally have an answer for this that appears to work.

同时编译 32 &64 位版本 - 托管和非托管 - 放入单独的文件夹中.然后让 .NET 应用程序在运行时选择从哪个目录加载程序集.

Compile both 32 & 64 bit versions - both managed & unmanaged - into separate folders. Then have the .NET app choose at run time which directory to load the assemblies from.

使用 ResolveEvent 的问题是只有在找不到程序集时才会调用它,因此很容易意外地以 32 位版本结束.而是使用第二个 AppDomain 对象,我们可以在其中更改 ApplicationBase 属性以指向正确的文件夹.所以你最终得到如下代码:

The problem with using the ResolveEvent is that it only gets called if assemblies aren't found, so it is all to easy to accidentally end up with 32 bit versions. Instead use a second AppDomain object where we can change the ApplicationBase property to point at the right folder. So you end up with code like:

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 个 exe - 您的普通应用程序和第二个切换应用程序,用于选择要加载的位.注意 - 我自己不能相信这个细节.我的一位同事给出了我的初步建议.如果他注册 StackOverflow,我会将答案分配给他

You end up with 2 exes - your normal app and a second switching app that chooses which bits to load. Note - I can't take credit for the details of this myself. One of my colleagues sussed that out given my initial pointer. If and when he signs up to StackOverflow I'll assign the answer to him

这篇关于如何在运行时延迟绑定 32 位/64 位库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆