Using a 64bit DLL in a 32bit Application - c#

XCode's ARC refactoring forced my Cocoa Library DLL to be 64bit, and I don't know if I can still DllImport that DLL from an x86 C# application. Is this possible, and are there any consequences of doing so?

You cannot mix 32 bit and 64 bit code in a single process. So the only way to use mix bitness code is to have more than one process. You'll need some form of IPC to make it work. You cannot do it with DllImport since that is in-process.

The problem is not really C# - it is the hosting process in the OS. Since one process can only load DLLs with the same "bitness", either the process is 64bit or you cannot directly load your DLL. No matter what language or framework you are using.
One solution would be to target the C# project to use "any" cpu or specifically point it to X64.
Another solution would be to create a hosting process that you can communicate with using IPC or similar models.

The solution when necessary is to call an EXE in pipeline or similar. This assumes of course a 64 bit windows. If not, punt.

Related

Is it good practice to design c# application under windows 64 bit?

I am new to c# . I am developing a C# application under windows 7 64 bit using visual studio 2015 professional. later when the application is ready I expect to install it in 64 bit or in 32 bit machines.
if I design the application under 64 bit I think it will not work under 32 bit, right? my question is: if I design it and then create setup file under 64 bit computer, what should I do later in order for my application to work under 32 bit windows machines?
Please help me. Thank you
if I design the application under 64 bit I think it will not work under 32 bit, right?
No. You can build an "Any CPU" assembly that will work in both. (You can also build a 32-bit assembly that will work in both, but on 64-bit it runs as a 32-bit app, which is rarely what you want).
my question is: if I design it and then create setup file under 64 bit computer, what should I do later in order for my application to work under 32 bit windows machines?
Test it in one. Selecting "Any CPU" is simple, but forgetting to do so is also simple, especially if you add another project for a library (an Any-CPU application with a 64-bit-only library is essentially 64-bit-only). Testing makes this very obvious, very soon.
If it's a managed application, generally it won't matter. The run-time will auto-magicly sort most problems simply by using Any CPU as target.
I've met 2 problems mostly:
developers who hard-code sizeof(int) to 4
managed applications with un-managed dependancies (like openssl libraries) - in this case you will need to have 2 different builds (one for 32 bit and one for 64 bit)
Your QAs should test your application on all target systems (even if by using virtual machines to do so).
Most .NET developers (I can't speak for C++ guys) use 64bit systems simply because we want performance and to use the newest stuff. All new CPUs support 64 bit for quite some time. It's no longer something exotic.
With .net it doesn't matters, just stick to "Any CPU" compilations and you should not have any problem.
Only exception is if you're using external libraries for an specific platform (unmanaged libraries or managed libraries specifically compiled for x64),
In the case of managed libraries you will need to compile twice, one for x86 and other for x64 with the correct libraries, on the unamnaged case you just need to declare the DllImports twice, one for each platform and use at runtime the correct ones.
It's a bit confusing to be honest...
... later when the application is ready I expect to install it in 64
bit or in 32 bit machines.
All 32-bit applications also work on 64-bit, because Intel/AMD made their AMD64 implementation backward compatible. In other words: regardless if you're using unmanaged or managed code, you can always run it on a 64-bit platform.
The other way around that's not the case, so:
if I design the application under 64 bit I think it will not work
under 32 bit, right?
Yes, correct.
Personally I don't bother anymore with x86 because everyone nowadays has a 64-bit capable processor.
It's usually best to compile to 'Any CPU'. The 'x86' and 'x64' targets are only there to enforce a certain platform. In practice everything is always compiler to .NET IL - which is JIT compiled by the runtime to native assembler.
The JIT uses the 'target flag' or the 'prefer 32-bit' (csproj properties) hint to determine which runtime should run the code. If
you have the 'x86' target or
'prefer 32-bit' (default) or
if you don't have a 64-bit system and don't have the 'prefer 32-bit' checked
it will use the x86 JIT compiler (and runtime). Otherwise it will use the x64 JIT compiler (and runtime).
There are some differences and subtleties that you change when you do this (that all have to do with native interop), but when you stick to normal C# code you shouldn't notice them.
Summary: Personally I seem to make it a habit of not being able to fit my application in 2 GB of RAM (I work what they now call 'big data'), so in those cases the best practice is to use the 'Any CPU' target and uncheck the 'prefer 32-bit'. That said, if you don't need the memory, it's probably better to leave it on as a safeguard.
my question is: if I design it and then create
setup file under 64 bit computer, what should I do later in order for
my application to work under 32 bit windows machines?
You might be surprised, but that's actually a totally different question. Setup systems (e.g. MSI) are highly dependent on the operating system. Most MSI's therefore use hacks to make it work on both platforms. Wix has some quite good documentation about this.

32bit dll in 64bit application in c#

Hello
I want to create a 64bit application in c# and I wan't to use in it a dll created in C++ builder (32bit). But when I try to load the dll the application crashes. When built in 32bit it works. Is there a way to use this dll in a 64bit app?
No this is not possible. A process in Windows is either 32 or 64 bit and it can only load DLL's which match. Any attempt to load a DLL which does not match will fail and produce an error.
If you need to match 32 and 64 bit code you need to use multiple processes. In this case though I would just make the application 32 bit or the DLL 64 bit
Do you want to build a 64-bit application, or you want to build an application that will run in a 64-bit environment? Your application can run perfectly fine in a 64-bit environment even when the target platform is x86.
You cannot load a 32-bit DLL into a 64-bit process on Windows.
I have never tried it myself, but you might be able to create a seperate 32-bit application that can run in a different process and act as a proxy for the DLL. Your application could then run 64-bit and communicate with the DLL with remote procedure calls over WCF.
If performance is a concern, then your best bet would be to rebuild the DLL in 64-bit, if possible.

Mixing 32-bit and 64-bit P/Invokes

I've run into a problem that I'm pretty sure I know the answer to, but I figured I'd at least ask and see if there was some "magic bullet" that might save me a huge headache.
Here's the high-level view.
I have a managed application. This application interfaces with hardware via third-party libraries from different vendors. I have full control over the consuming managed app and zero control over the hardware API libraries.
Vendor A provides only a 32-bit native SDK. To allow us to use it on 64-bit systems, we marked the application to run in 32-bit mode. All was well.
We are now integrating with Vendor B, which provides 64-bit-specific native API libraries on 64-bit machines. The 32-bit native DLL from Vendor B will not work on a 64-bit system (tried that). If I build a test harness running as 64-bit or AnyCPU, it works fine. If I mark it as 32-bit, it fails on the P/Invoke calls.
It seems that Vendor A and Vendor B hardware are going to be mutually exclusive on 64-bit PCs, but I'm wondering if anyone has suggestions on how to possibly work around that.
The problem is not a .NET or P/Invoke. It is an OS issue. A 64-bit process can only load 64-bit DLLs. A 32-bit process can only load 32-bit DLLs. The magical Windows-on-Windows (or WoW) layer that lets 32-bit apps run on 64-bit Windows exists between the user-mode process (EXE and DLLs) and the kernel. There is no way to run a 32-bit DLL inside a 64-bit process. The WoW layer exists below that. (Basically WoW is a 32-bit wrapper around the 64-bit Win32 API, which marshals data and function calls between the 32-bit world of the process and the 64-bit world of the operating system.)
Your best/only option is to run your 32-bit and 64-bit components in separate processes and use some form of IPC to communicate. This has the added benefit of decoupling your core application from potentially unstable 3rd-party components. If a 3rd-party component crashes or misbehaves, it's simply a matter of re-starting the process containing that component.
You can make a separate 32-bit process to interact with Vendor A, then communicate with it using WCF.
Since you can't load 32 bit and 64 bit images into the same process, you'll have to use a multi-process solution.
Hopefully someone can suggest a better alternative, but perhaps you could wrap one of the libraries (whichever one has the lowest bandwidth connection to your app) in a separate process, and then communicate with it (e.g. via sockets).

Will a .NET Windows Forms application work in a 64-bit OS or does it need to be modified?

Generally speaking, will a .NET Windows Forms application work in a 64-bit OS or does it need to be modified?
If it doesn't rely on a 32 bit external library (e.g. COM component), it'll work perfectly as a 64 bit process and will leverage its benefits (large address space, x64 instruction set, ...). If it relies on 32 bit stuff, most of the time, you can still run it as a 32 bit application by setting the target platform to x86.
Most .NET applications should work unmodified in 64 bits if they target x86 instead of Any CPU which is the VS.NET default.
According to this link: MSDN - Migrating 32-bit Managed Code to 64-bit.
If you have 100% type safe managed code then you really can just copy it to the 64-bit platform and run it successfully under the 64-bit CLR.
But if you are using any of the following features:
Invoking platform APIs via p/invoke
Invoking COM objects
Making use of unsafe code
Using marshaling as a mechanism for sharing information
Using serialization as a way of persisting state
it indicates that the application might not be completely compatible.
For the most part it should work just fine. You should be careful if you are doing anything with native code, whether it be unsafe managed code, or interop/PInvoke, but if all of your code is managed you shouldn't have any problems.
A pure .NET application will run on a 64-bit operating system with no modifications.
If you use a C++/CLI library, use architecture specific COM components, or do any P/Invoke calls, you may need to update your application for a 64-bit environment.
Most 64-bit OS's are able to handle 32-bit apps without problems. This is why you see a Program Files (x86) folder on your 64-bit OS to handle a lot of your old 32-bit apps.
As long as you don't mix and match library platforms, you'll be fine. Target x86 when you compile and you should be good to go.

DirectX application on 64 bit windows

I am developing a WPF application where the 3D part is handled by DirectX 9 (a lot of 3d that did not run fast enough using WPF).
The problem is the application is released with "Any CPU" as configuration and when a user runs it on a 64 bit windows, the direcX part crashes (System.BadImageFormatException). Apparently the dlls included for the directX part is not usable on a 64 bit windows.
This has happened with some other 3:rd part dlls that we use in our application but this we have solved by changing the dlls in runtime to the ones built for x64 if the user are running on a 64 bit windows machine. Do any of you know where I can find DirectX 9 dlls for x64? If they exist at all.
The ones I need are:
Microsoft.DirectX.Direct3D
Microsoft.DirectX.Direct3DX
Microsoft.DirectX
If they do not exist, can the problem be solved in some other way? I cannot change the configuration to x86 because the application is released via ClickOnce and a change of configuration make ClickOnce stop working (the configuration is included in the ClickOnce key)
Let me add that the I am using a Winforms part hosted by the WPF application and that the winforms part is using the DirectX dlls I am asking about. This was a much better and faster way of presenting a lot of 3D meshes in WPF than to use WPF:s 3D. Unfortunately this problem occurred instead.
The DLL's you need are for Managed DirectX. Unfortunately Microsoft no longer supports Managed DirectX and it's successor, XNA does not support 64bit either.
SlimDX is an open source alternative to Managed DirectX, and it supports 64bit. The other option is to write the DirectX code in unmanaged C++.
You can set your WPF application to only run as a 32-bit app. Post your ClickOnce problem as another SO question. This is probably your best option.
Project Properties -> Build -> Platform Target -> x86

Categories