I'm trying to embed SQLite into my portable C# .NET 2.0 application rather than having the DLL files included in the distribution folder. However, to embed SQLite, I cannot use the Mixed-Mode libraries provided by PHXSoftware. Instead, I am using their 'Managed Only' version.
This works fine on 32-bit computers, but when it's running on a 64-bit machine, it throws a format exception. As I found out from here: http://sqlite.phxsoftware.com/forums/p/2564/9939.aspx I need to load the unmanaged sqlite3.dll manually in the required architecture format first before I use the managed libraries.
That's where I fall short. I cannot find a 64-bit version of SQLite to include along with the 32-bit one. Can anyone help? Dare I say, does anyone have any better ideas?
I'd recommend you build the source yourself. It's very straight-forward to do. Especially considering Sqlite offers amalgamation source.
Here are the compiler pre-processor defines I use for a 64-bit release build:
WIN64 NDEBUG
_WINDOWS
_USRDLL
NO_TCL
_CRT_SECURE_NO_DEPRECATE
THREADSAFE=1
TEMP_STORE=1
SQLITE_MAX_EXPR_DEPTH=0
Here are the compiler pre-processor defines I use for a 32-bit release build:
WIN32
NDEBUG
_WINDOWS
_USRDLL
NO_TCL
_CRT_SECURE_NO_DEPRECATE
THREADSAFE=1
TEMP_STORE=1
SQLITE_MAX_EXPR_DEPTH=0
The System.Data.SQLite fork has x86/x64 binaries for .Net 2, 3.5, and 4. Downloads are here.
Update:
Another possible solution is to target your application for x86 platform and just use the x86 SQLite libraries. If your application doesn't require x64 features targeting the x86 platform will greatly reduce the complexity of your deployment.
Related
is it possible to create a AnyCpu assembly with SWIG? I have both the x86 and x64 binaries compiled (c++) and I'm able to generate a SWIG P/Invoke Wrapper. But the wrapper is dependent on the invoked native dll (which is CPU specific). But I like the idea of let the executable decide instead of having two different executables. I'm would put the dlls in seperate folders (e.g. named x64/x86) if this is helpful. Or do I have to write a handmade wrapper in C# which decides to load the right dll?
Thanx for input.
It seems you have to roll you own wrapper.
I came across the solution CLRZMQ was using for similar reasons.
They solved it pretty well by embedding both .dll versions and extracting those accoring to the current platform:
They determined the running platform by using Environment.Is64BitProcess and adding a x86 or x64 suffixe + version string before extracting and loading the correct dll.
Here is their solution to the problem and here is the corresponding discussion which gives different ideas on how to solve it. Also interesting is their SafeLibraryHandle which I just found out about.
I have a C++/CLI Managed Library that I built both for x86 and x64.
I use this library in a C# Project that I am building for Any CPU. And I am using the x64 Version of my C++/CLI Managed Library.
After looking at this question where some techniques to build using either the x86 or x64 dlls according the platform of your project.
I wonder, if it is possible to indicate the designer to use the x86 version of my library, while my application could still be using the x64?
Right now my designer shows errors if I try to use in my View Models anything that belongs to the x64 Library.
I'm attempting to use a CAN device over USB that comes with a native DLL that needs to be wrapped by a .NET C# class (source code provided by the vendor) that gets included in one's project. Their sample applications target .NET 2.0 where my application targets .NET 4.0. I'm able to use the code in their sample apps and debug everything just fine, however, when I try to debug my application, I get a BadImageFormatException:
System.TypeInitializationException: The type initializer for 'TotalPhase.KomodoApi' threw an exception. ---> System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
The only differences between their code and mine appears to be that their code is an application built for .NET 2.0 and (currently) my code is running as an MSTest unit test in .NET 4.0. Both solutions target AnyCPU. I'm running on a Windows 7 Ultimate 64-bit install. Even changing from AnyCPU to x86 didn't make any difference. How can I get this native DLL to load in an AnyCPU project?
If you get a BadImageFormatException when interfacing with a native DLL, it almost always means that you are trying to interface with a 32-bit DLL while running in the 64-bit CLR, or vice versa.
When you run the sample applications, do the processes have *32 in the "Image Name" column of Task Manager's "Processes" tab? That indicates the applications are running in the 32-bit CLR. Check your own application as well. It is possible that the machine you are testing on only has a 32-bit .NET 2.0 runtime, but both 32-bit and 64-bit .NET 4.0 runtimes, or the other way around.
If you are distributing a native DLL with your .NET application, then you should set your startup project to target x86 or x64 (as opposed to AnyCPU), depending on whether the native libraries are 32-bit or 64-bit. You can always ship both 32-bit and 64-bit versions, and let the installer choose which binaries to install based on the client architecture.
Alternatively, you can ship both 32-bit and 64-bit DLLs with different file names, define separate P/Invoke stubs for each version, and decide which one to call at runtime. The easiest way to do this would probably be to wrap your native calls in an interface (e.g., INativeMethods) and choose which implementation to instantiate at runtime based on IntPtr.Size. With this method, you could still target AnyCPU.
I am writing an application in C#, which is cross platform. It uses DllImport for several different libraries. It is also both x32 and x64.
It seems to work right for my own compiled .dll/.so. I put the x32 shared libraries in the x32 sub-folder, and the x64 shared libraries in the x64 sub-folder.
On windows via .net framework I call SetDllDirectory("x32" or "x64") depending on the current
runtime. On mono, either through windows, linux or mac, I use a DllMap, in RandomLibrary.dll.config. It works fine for files that are located in the x32 or x64 directories.
However, I also use DllImport for libraries that I didn't write, such as FreeType2. On windows, I just shove the built libraries in the two sub-folders. However on linux I would rather use the libfreetype6 library that you can install via your friendly local package manager. I can hardcode the DllMap link to /usr/lib/x86_64-linux-gnu/libfreetype.so.6, but I assume that the freetype file will change depending on what distro you use.
Is there any easy way where it can just find libfreetype.so regardless of what distro I am using?
Using DllImport("libfreetype.so.6") for Linux should be enough, as the system should be configured to handle it correctly. Make sure you have the correct packages installed.
If it doesn't work you may have a misconfigured system: post the errors you get, the LD_LIBRARY_PATH env var value, the contents of /etc/ld.so.conf and the files in /etc/ld.so.conf.d/.
The output of
/sbin/ldconfig -p |grep freetype
would be useful as well.
Mono have a thing/procedure specifically for this, it is called DllMap. You can specify which unmanaged libaray gets loaded on which platform. Eg:
<configuration>
<dllmap dll="foobar" os="linux" wordsize="64" target="linux/amd64/libfoobar.so" />
<dllmap dll="foobar" os="linux" wordsize="32" target="linux/i386/libfoobar.so" />
</configuration>
I've not tried the above myself - The dllmap docs seem to hint that the target value isn't a path but I can't be sure.
Another approach would be to have a simple shellscript or batch file. On linux the shell script could easily work out the architecture by calling arch and set LD_LIBRARY_PATH accordingly. I generally prefer a shell wrapper around my mono programs ( seeing MyProgram.exe on the console feels ugly )
Lastly you might have more fun if you pinvoke into dlopen or LoadLibarary to pre-load your shared libraries.
When your managed app starts you decide what architecture you are and then use dlopen() if on linux or LoadLibaray() if on windows.
I have visited this and found no answer How to convert a .NET exe to native Win32 exe? for me. I am searching for a program that converts .net exe to win32 exe. Is that possible ? I have run ngen.exe from Microsoft, but when I write the command that should convert the assembly, it tells that converting successed, but I don't find the converted exe:
This is the command:
start ngen install C:\program.exe /debug
You need a much bigger weapon to create a native win32 executable from a managed program. Ngen.exe merely pre-compiles the IL, the CLR and the original assemblies are still needed to run the program.
The kind of tool you need was somewhat popular in the early days of .NET when programmers were fretting about getting the .NET framework installed on the target machine. They are known as ".NET linkers", Salamander was popular. No idea if it has kept up with .NET versions, you definitely want to verify the trial version first. Also beware of the considerable sticker-shock you'll suffer.
I think ngen.exe installs the native image in the cache. So you don't really see it as a file on disk, but it will run when you invoke the application.
You can see what images are in the cache with
ngen display