Can a project with AnyCpu architecture take different libraries depending on the pointer size? Those. something like this:

internal class SdlFunctions { private const string DllNameX64 = "x64\\sdl2.dll"; private const string DllNameX86 = "x86\\sdl2.dll"; #region SDL_video.h /// <summary> /// Get the number of video drivers compiled into SDL. /// </summary> [DllImport(DllNameX86, CallingConvention = CallingConvention.Cdecl)] internal static extern int SDL_GetNumVideoDrivers(); [DllImport(Is64Bit ? DllNameX86 : DllNameX64, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] internal static extern IntPtr SDL_CreateWindow(); #endregion private static bool Is64Bit => IntPtr.Size != 4; } 

But this will not work, because in the attribute DllImport need to pass a constant.

Is there anything else other than using the (Load\Free)Library ?

  • There is another option with # if / # else. Either drag both exes and check the bit length before each function call to call the appropriate one. There is a third option - with aop, but I do not think that in your case it is worth the candle - Alexander
  • @Alexander: I wrote AnyCpu, i.e. it is assumed that the library will work on any platform, which means it will carry with it both versions of the bit. - LLENN pm
  • then the option with # if / # else disappears. All that remains is after - Alexander
  • Look here . English is not needed - everything is in the code. There, the first two answers are of interest: 1) Register two functions at a time, for example, SDL_CreateWindow_32 and SDL_CreateWindow_64 , and in the code already check the bit depth and call the desired one. There will be no errors, because the library is loaded when it is called 2) When initializing the class where these functions are stored, dynamically load the necessary library. Functions from it will already be picked up automatically - a more elegant way and your case fits it. - John

1 answer 1

If the configuration is exactly what you described: unmanaged modules for different architectures have the same name and are located in different subdirectories of the program directory, you can use the SetDllDirectory function. When launching the application, call SetDllDirectory, passing the x86 or x64 directory depending on the current architecture. The P / Invoke declaration for each function should leave one that contains only the name dll, without the path to the subdirectory. When starting, the program will search for the dll first in the program directory, then in the SetDllDirectory directory, and then in the system directories, so dll should not be in the program directory with the same name to make it work.

 [DllImport("kernel32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool SetDllDirectory(string lpPathName); static void InitializeDll(){ string path = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath; string dir = Path.GetDirectoryName(path); string subdir; if(Environment.Is64BitProcess) subdir = Path.Combine(dir,"x64"); else subdir = Path.Combine(dir,"x86"); SetDllDirectory(subdir); } 

But, a more logical and WinAPI-independent solution is to have two P / Invoke declarations for each function and method, which is necessary depending on the architecture.