Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading x86 or x64 assembly

Tags:

c#

.net

x86

64-bit

I have two versions of System.Data.SQLite.DLL - for x86 and x64 platform. The x86 version keeps in application folder and x64 version keeps in appFolder\x64 folder. The application compiled as AnyCPU. How can i load needed version of SQLite according to windows platform?

like image 882
Rover Avatar asked Sep 24 '10 13:09

Rover


People also ask

What is x64 Assembly?

This Gem is an introduction to x64 assembly. No prior knowledge of x86 code is needed, although it makes the transition easier. x64 is a generic name for the 64-bit extensions to Intel‟s and AMD‟s 32-bit x86 instruction set architecture (ISA). AMD introduced the first version of x64, initially called x86-64 and later renamed AMD64.

What is the difference between x86 and x64?

No prior knowledge of x86 code is needed, although it makes the transition easier. x64 is a generic name for the 64-bit extensions to Intel‟s and AMD‟s 32-bit x86 instruction set architecture (ISA). AMD introduced the first version of x64, initially called x86-64 and later renamed AMD64. Intel named their implementation IA-32e and then EMT64.

Should I start with 32-bit or 64-bit assembler?

There is a lot more going on in the 64-bit case, so starting with 32-bit is probably good; you just need to make sure you're assembling your program with a 32-bit assembler into a 32-bit binary. Windows will still know how to run it.

What are the best resources for learning x86 assembly?

x86 tag wiki (beginner guides, reference manuals, ABI documentation, and more.) X86 Dissassembly WikiBook (great for understanding some conventions, and the basics of how higher level code translates into assembly) Assembly Tutorial (great for helping to understand core concepts)


2 Answers

If you are using SQLite from http://system.data.sqlite.org, the System.Data.SQLite.DLL is completely managed. There is an underlying native DLL, SQLite.Interop.DLL, that needs to change depending on the process (32- or 64-bit).

I deploy the native libraries in ".\Native\X64" for 64-bit and ".\Native\X86" for 32-bit. At runtime P/Invoke SetDllDirectory to set the DLL load directory pointing at the correct path for the process. http://msdn.microsoft.com/en-us/library/ms686203(v=vs.85).aspx

(Note that I'm not familiar with the architecture of the legacy System.Data.SQLite.DLL version from http://sqlite.phxsoftware.com)

private static class NativeMethods
{
    [DllImport("kernel32.dll", CallingConvention = CallingConvention.Cdecl)]
    internal static extern bool SetDllDirectory(string pathName);
}

... 

    // Underlying SQLite libraries are native. 
    // Manually set the DLL load path depending on the process.
    var path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Native");
    if(IntPtr.Size == 8) // or: if(Environment.Is64BitProcess) // .NET 4.0
    {
        path = Path.Combine(path, "X64");
    }
    else
    {
        // X32
        path = Path.Combine(path, "X86");
    }
    NativeMethods.SetDllDirectory(path);
like image 66
Jason Morse Avatar answered Oct 06 '22 00:10

Jason Morse


Some antivir progs prevent SetDllDirectory() - took me a long time to realize that. We are using

System.Reflection.Assembly myass = System.Reflection.Assembly.GetExecutingAssembly();
FileInfo fi = new FileInfo(myass.Location);
System.IntPtr moduleHandle = LoadLibraryEx(fi.Directory.FullName + "\\x64\\SQLite.Interop.DLL", IntPtr.Zero, 0);

to load the x64 DLL with explicit path. It is loaded at that point and the .NET Runtime will use the in-memory DLL instead of searching the disk for it.

like image 39
Patrick Avatar answered Oct 06 '22 00:10

Patrick