Our application is all 64 bit. We got ADODB provider to 3rd party database (nexusdb). It's 32 bit and consists of .NET library (which we reference just fine) and I beleive C .dll which is 32 bit. So, when we compile in 32 bit it works, in 64 it complains that it can't find C .dll.
How can we solve this issue without compiling our code to 32 bit?
EDIT:
3rd party DLL's as follow:
ADONET.dll - this is .NET native DLL that I reference and it references just fine.
ADONETProvider.dll - this is non-.NET 32 bit DLL that I just keep in bin/ folder.
I DO NOT want to compile my project for x86 because I reference many other projects and they all 64.
I want to make sure that ADONET.dll somehow called in "32 bit mode"
You have to use some kind of surrogate process and IPC to access a 32 bit dll from a 64bit process.
Some time ago I wrote the LegacyWrapper project that hides this behind a simple API call. You may want to see the corresponding blog post for technical details.
Edit: Since Version 2.1, LegacyWrapper also supports loading 64bit DLLs from a 32bit process.
Related
I have a .NET application that calls a C++ API using P/Invoke. The C++ dll has a dependency from a third-party dll. That third party dll calls LoadLibrary to dynamically load libeay32.dll, an OpenSSL dependency.
After doing several tests I found out that the .NET application works correctly in Windows 10 but fails in some deployments using Windows 7. The cause of the failure is because the .NET process is not loading libeay32.dll. I tried placing libeay32.dll in the same directory as the process and in the System folder (having in mind the Dynamically load search order) but the failure persisted in Windows 7 32 bits only. Furthermore, if I called the API dll from a C++ console application it worked without issues in all platforms. To solve the problem I called LoadLibrary in the .NET application, before making the P/Invoke calls to the C++ API, and it worked in all target platforms (Windows 10/7 32 and 64 bits).
Why would LoadLibrary fail to load libeay32.dll in Windows 7 but not Windows 10 if called from the C++ dll dependency of the API called using P/Invoke?
Edit
Some notes from comments:
All the compiled assemblies are targeted for x86 architecture.
Before posting the question, I verified that no dependencies files
where missing, using dependency walker.
Likely because the dll is depending on some files that are missing. Use dependency walker and see what files it requires. Check on both systems. The tool will show you in red the missing files. Do not blindly copy the files.See what they are, what runtime or setup is required to deploy them, and deploy them properly.
.Net applications can be built with AnyCPU as their target and run in both 64 and 32 bit modes, but if you choose AnyCPU for your target the operating system will choose one based on it's preference. What this can mean if you have native dependencies is that the library that you're depending on can't be loaded because you're running in the wrong bitness. If you can constrain the application to the bitness you're expecting it might work better.
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.
I have to upgrade a project from 32 bit to 64 bit. My project is currently on .net 2.0 (will be soon 4.0, but doesn't really matter for this issue). My project is referencing some old .net 1.1 assemblies, that I only have in binary form. As you all know, 64 bit support was added in .net 2.0 only, and I expected my application won't run because of those old assemblies.
However, my application runs on a x64 server in 64 bit mode (no star is shown in Task Manager) while referencing the .net 1.1 dll.
My questions are:
Why does it run? I previously read that you cannot use .net 1.1
assemblies in 64 bit apps.
Are there any shortcomings if I keep the 1.1 assemblies? Or should I invest effort in getting newer versions of those 1.1 assemblies?
EDIT: I forgot to mention that a requirement is to run the application (asp.net) natively in 64 bit. The application runs in 64 bit because I disabled 32 bit compatibility on my application pool.
EDIT2: I just tried to compile and run the application compiled for x64. It works. So it runs in pure 64 bit mode, no questions about it.
A .NET 1.1 assembly contains the same kind of IL as a .NET 2 or .NET 4 assembly. Only the format of the metadata has changed. The jitter doesn't mind translating it to 64-bit machine code and the CLR can read the old metadata format. Only if the .NET 1.1 assembly contains native code will you have a problem. Corflags.exe utility, ILONLY bit. There's no compelling reason to rebuild that assembly.
Is your application running under wow32 (32-bit emulation mode)? Most applications do not really run in x64 mode, they force the application to run in wow32 (x86 mode) to keep their backward compatibility on older x86 systems. Otherwise the application would run only on x64 systems but not on x86.
Forcing the application to run in x86 mode (even on x64 systems) allows to run ony any manchine no matter if its a 32 or 64 bit windows OS.
By default, my application references a mixed mode DLL, so this DLL is both 32 and 64 bit. On a 32 bit system, my app is MSIL and loads the 32 bit DLL. On a 64 bit system, my app loads the 64 bit.
However on a 64 bit system, in an older version of the assembly that I am referencing, they only created a 32 bit version. So I fail to load this. I was looking at doing it dynamically, and ideally I would want my MSIL app in 64 bit mode to load the 32 bit DLL. Is this possible?
Also it would be nice to resolve it to a different version than what I have referenced as well.
Any help appreciated.
You cannot load 32-bit DLLs into 64-bit processes. "Any CPU" assemblies work because the JIT handles the IL compilation before execution, creating a native image of the appropriate type; CPU-specific assemblies don't support JITing to different types.
This is a Windows limitation, not a CLR limitation.
I have compiled a .NET application using Any CPU option. This .NET application uses an unmanaged dll (managed wrapper) that encapsulated C++ calls. This .NET wrapper resides in GAC.
When I run the .NET application it runs fine on XP 32 bit. But when I run it on XP 64 bit, it fails and gives the following exception:
Could not load file or assembly "Dll name, version, Culture=neutral, PublicKeyToken" or one of its dependencies.
How do I resolve this?
You need to use the x86 CPU option. If you know that one of your unmanaged dependencies is 32bit then you need to build your solution with the x86 option for the CPU. This ensures that even on a 64bit operating system your application will be run in a 32 bit process.
This is required because its not possible to load 32 bit compiled code into a 64 bit process.
You need to make sure your unmanaged dll is also 64bit capable and within the search path.
You can find some explanation on Microsoft Connect website