Jasica.Net

C#, .Net, SQL i nie tylko

Dynamiczny wybór wersji pomiędzy wersjami x86 oraz x64 natywnych bibliotek

Targetowanie projektu na architekturę x86 przy współpracy z natywnymi bibliotekami może nie być eleganckim rozwiązaniem, zwłaszcza jeśli dostępna jest w wersji 32 i 64 bitowej. Można tego uniknąć dokonując wyboru wersji biblioteki natywnej w czasie wykonywania programu.

Podobny problem w świecie kodu zarządzanego można by rozwiązać przy pomocy zdarzenia AssemblyResolve AppDomeny, która miałaby załadować kod. Co zrobić jednak, gdy biblioteka jest tylko wraperem na natywne wywołania? Należy w katalogu z plikami wykonywalnymi stworzyć dwa dodatkowe katalogi, w których znajdą się biblioteki skąpilowane na daną platformę(np. "\x64" i "\x32"). Natomiast czy aplikacja działa jako proces 32 czy 64 bitowy można sprawdzić przy pomocy właściwość Is64BitProcess klasy Environment. Na koniec należy jeszcze wskazać na podstawie wcześniej poczynionych kroków, gdzie system powinien szukać bibliotek. Najprościej to uczynić przy pomocy natywnej funkcji SetDllDirectory. Przykładowy kod może wygląda tak:

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool SetDllDirectory(string lpPathName);

        private static void Init()
        {
            var location = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            var type = Environment.Is64BitProcess ? "x64" : "x86";
            var path = Path.Combine(location, type);
            SetDllDirectory(path);
        }