I'm writing a program in .NET 3.5, that in some places has to go out and execute code from hardware APIs. This is all good, and working in 32-bit Windows 7, Windows XP, etc. The problem comes with Windows 7 64 bit.
I compile in 'Any CPU', and it does run in 64 bit on Windows 7 64 bit. So, to interface with this one piece of hardware, I had to write my own wrapper DLL, in unmanaged C++.
So, after I had it all working in 32 bit, I then flipped the switches to go to 64 bit, and therein lies the problem. The issue I'm having is pretty much the EXACT opposite of Stack Overflow question “An attempt was made to load a program with an incorrect format” even when the platforms are the same... In that question, he's trying to get his code to run in 32 bit (force it to) on Windows 7.
OK, now, I don't want to do that, since there IS a 64 bit API for this piece of hardware. So, I compiled my code in 64 bit, and then after a lot of trial and error, I got it LINK properly in 64 bit, and I have a PURE 64-bit native C++ DLL, and Depends.exe
confirms that. Now, Depends.exe
also displays the vendor's DLL file as pure 64 bit. Which is good, because the first time the code didn't work, I started the research with the manufacturer, and they have updated their code quite a bit with my help, or should I say with my ISSUES... :)
So, short story long, I've broken this down to as simple a setup as I can. My DLL file, the HW API.dll
, (which is also native C++), and a .NET application to call them, using the same P/Invoke syntax, and calls as the 64-bit version...
My calls, just for reference look like this:
[DllImport("xBiometrics.dll", ExactSpelling=true, SetLastError=true)]
[return: MarshalAs(UnmanagedType.I4)]
public static extern Int32 bioScanOpenDevice();
Now, when I attempt to call this code, from .NET, I get an exception error:
"System.BadImageFormatException:
An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)"
This leads me to belive that SOMEHOW, something 32 bit is interfeering... How could I possibly tell that? I mean, yes, I've already looked into the resource explorer, and made sure that the DLL files were getting loaded from the correct place, and again, they ARE compiled in 64 bit, and the .NET application is running in 64 bit, even though it's compiled for "Any CPU". I've verified all this...
Am I being totally stupid about something here? Did I miss the paragraph where it tells us that P/Invoke does not work on 64 bit or something? And if I did, why is it throwing a bad image format exception?
Is what I'm doing even possible or not? Can a 64 bit .NET application, load, and call a 64 bit native DLL file? And can THAT DLL file dynamically link to another native 64-bit DLL file? Would it make a difference if I used a managed 64-bit DLL file as the wedge DLL file? I'm only using a wedge DLL file because of some of the calls in the hardware vendor's DLL file. They pass void pointers to buffers, and such and it got to be too complicated to do in C# (having to have the "Allow Unsafe Code" checked, etc.) So, my wedge idea worked much better... I do all the heavy lifting in C++ and pass back more structured data to the C# code.