Dynamically calling 32-bit or 64-bit DLL from c# application using Environment.Is64BitProcess

巧了我就是萌 提交于 2019-12-05 17:30:16

Lots of ways to do this:

  • this is a deployment problem, just get the right DLL copied by the installer, give them the same name

  • very few programs actually need the massive address space provided by 64-bit code. Just set the Platform target to x86

  • use the EntryPoint field of the [DllImport] attribute. Set it to "KFUNC". And give the methods different names. Now you can call one or the other, based on the value of IntPtr.Size

Demonstrating the last solution:

[DllImport("KEYDLL32.DLL", EntryPoint = "KFUNC")]
private static extern uint KFUNC32(int arg1, int arg2, int arg3, int arg4);

[DllImport("KEYDLL64.DLL", EntryPoint = "KFUNC")]
private static extern uint KFUNC64(int arg1, int arg2, int arg3, int arg4);

...

if (IntPtr.Size == 8) KFUNC64(1, 2, 3, 4);
else                  KFUNC32(1, 2, 3, 4);

Ironically, on a 64-bit system, kernel32.dll (residing in %windir%\System32\) is the 64-bit version, and the %windir%\SysWOW64\ version is the 32-bit system. Extremely unfortunate naming going on here...

Anyway, what you can do is bind to both versions, using the paths as I linked them, to two different variable names (say, LoadLibrary for the system32 version and LoadLibrary32 for the syswow64 version). Then on a 32 bit system you can just use LoadLibrary, and if you detect a 64 bit system, LoadLibrary will be the 64-bit version, while LoadLibrary32 will be the 32-bit version.

I question however that this will help you any since I don't think you can dynamically bind to mismatching bitness (gonna make this the word!) dynamic libraries... Would help your second example I guess, where you actually do get two different libraries, one for each case.

Instead of doing so low level interop I would consider going more .Net route - use plugin-like assemblies to deal with it.

  • create 2 assemblies that link to x86 and x64 versions of the DLL (and compiled for correct platform).
  • Make this assemblies to expose class(es) implementing the same interface (or some other way of making them the same). Make sure the rest of you code can use either of the libraries, may need third assembly with base types/interfaces.
  • At run time load the assembly that you need manually. Make sure that it does not happen to be in search path to avoid loading one automatically by mistake.

Note that your second approach (picking methods based on bitness) should work fine. I would still wrap all access to each DLL in classes with same interfaces and make sure that only correct one can be instantiated at run time.

Keeping the dlls in two different directories and call them dynamically.

Libs64\ABC.dll
Libs32\ABC.dll

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!