Dynamically invoking a 32-bit or 64-bit DLL from a C # application using an environment. Is64BitProcess

I am working on a project written in C # for .NET 4.0 (through Visual Studio 2010). There is a third-party tool that requires the use of a C / C ++ DLL, and there are examples for 32-bit applications and 64-bit applications in C #.

The problem is that the 32-bit demo is statically linked to the 32-bit DLL, and the 64-bit demo is statically referenced to the 64-bit DLL. Being a .NET application, it can be launched either as a 32-bit or 64-bit process on client PCs.

The .NET 4.0 framework provides the Environment.Is64BitProcess property, which returns true if the application is running as a 64-bit process.

What I would like to do is dynamically load the correct DLL after checking the Is64BitProcess property. However, when I explore dynamic library loading, I always come up with the following:

[DllImport("kernel32.dll")] public static extern IntPtr LoadLibrary(string dllToLoad); [DllImport("kernel32.dll")] public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName); [DllImport("kernel32.dll")] public static extern bool FreeLibrary(IntPtr hModule); 

These methods appear to be specifically designed for the 32-bit operating system. Are there 64-bit equivalents?

Can a problem statically link both 32-bit and 64-bit libraries if the corresponding methods are called based on the Is64BitProcess check?

 public class key32 { [DllImport("KEYDLL32.DLL", CharSet = CharSet.Auto)] private static extern uint KFUNC(int arg1, int arg2, int arg3, int arg4); public static bool IsValid() { ... calls KFUNC() ... } } public class key64 { [DllImport("KEYDLL64.DLL", CharSet = CharSet.Auto)] private static extern uint KFUNC(int arg1, int arg2, int arg3, int arg4); public static bool IsValid() { ... calls KFUNC() ... } } 

...

 if (Environment.Is64BitProcess) { Key64.IsValid(); } else { Key32.IsValid(); } 

Thanks!

+4
source share
4 answers

Many ways to do this:

  • This is a deployment problem, just get the correct 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 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

Demonstration of 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); 
+4
source

Ironically, in a 64-bit system, kernel32.dll (located in %windir%\System32\ ) is a 64-bit version, and %windir%\SysWOW64\ is a 32-bit version. Extremely unsuccessful naming occurs here ...

In any case, what you can do is bind to both versions, using the paths when I linked them, with two different variable names (for example, LoadLibrary for version system32 and LoadLibrary32 for version syswow64 ). Then on a 32-bit system, you can simply use LoadLibrary , and if you find a 64-bit system, LoadLibrary will be a 64-bit version, and LoadLibrary32 will be a 32-bit version.

I doubt this will help you, since I don’t think you can dynamically link to bit mismatch (make that word!) Dynamic libraries ... It would help your second example, I think where you actually get two different libraries, one for each case.

+1
source

Instead of doing this low-level interop, I would think about moving on .Net route - use plugin-like assemblies to deal with it.

  • create 2 assemblies that reference the x86 and x64 versions of the DLL (and compiled for the correct platform).
  • Make these assemblies to show the class (s) implementing the same interface (or another way to make them the same). Make sure that the rest of the code can use any of the libraries; a third assembly with basic types / interfaces may be required.
  • At run time, download the assembly you need manually. Make sure it is not in the search path to avoid automatic download by mistake.

Please note that your second approach (bit-based collection methods) should work fine. Anyway, I will wrap all access to each DLL in classes with the same interfaces and make sure that only the correct one can be created at runtime.

0
source

Saving libraries in two different directories and their dynamic use.

Libs64 \ abc.dll
Libs32 \ abc.dll

0
source

Source: https://habr.com/ru/post/1414411/


All Articles