I'm not asking for the SO to tell me what the problem is, I'm just asking what sanity checks should I run in a case like this.
Using Visual Studio 2005, plain c++ project. Actual code is:
int Sum(int a, int b)
{
return a+b;
}
No pre-compiled headers. Exported with a DEF file:
LIBRARY testdll
EXPORTS
Sum
Compiled on a test machine (VS2005 again), the DLL works on other machines (64 bit and 32 bit tested, always compiled with a Win32 target platform). Compiled on my machine (64 bit, same project, same properties), the DLL works only on my machine, on others it starts the Just-In-Time Debugger (or crashes horribly if JIT isn't installed):
Unhandled exception at 0x00000000 in Caller.exe: 0xC0000005: Access violation reading location 0x00000000.
At first I was calling it with j on my test machines, and that would fail too, giving me (with cder) a "file not found" error.
Other symptom: File size is different, my machine gives the DLL an extra 512 bytes.
My system configuration:
Windows Vista - 64 bit
VS2005 Version 8.050727.867 (vsvista.050727-8600)
.NET Framework Version 2.0.50727 SP2
Tested environments:
Windows XP - 32 bit (virtual machine)
VS2005 Version 8.0.50727.42 (RTM.050727-4200)
.NET Framework Version 2.0.50727 SP2
Windows XP - 64 bit
VS2005 Version 8.0.50727.42 (RTM.050727-4200)
.NET Framework Version 2.0.50727 SP2
I suppose that "Win32 target platform" is wrong configured on your 64-bit machine. I recommend you to start "Visual Studio 2005 Command Prompt" and use
dumpbin.exe /headers YouDll.dll
to examine the "wrong" DLL which will be produced on the 64-bit machine. You can compare it with the "good" DLL. I suppose that you will immediately see the differences. WinDiff.exe can help you additionally.
One small general advice: consider to use EXTERN_C and WINAPI (or __stdcall) for all functions which you export from the DLL.
Open both DLLs in Dependency Walker and see what's different. Preferably do this on a machine where one DLL doesn't run right.
Related
I am compiling a dll in visual studio 2017 c++.
SDK: 10.0.17134.0
this project uses a template, that automatically creates 2 dll, one for 32 bit and one for 64 bit. I do have two machines that run the same software but have different hardware and OS.
First machine has a intel i7 and runs windows embedded standard 64 bit
the second machine has a intel atom and runs windows embedded standard 32 bit
On the 64 bit machine, both dll work. (32 bit and 64 bit), on the atom the 32 bit does not work tough. I do not have any error messages, the only thing i get from the software is that it is not compatible without any additional clues. The software is the same on both systems so I assume that the problem is related to the OS or the processor.
the software I am developing for is a vision system by omron so it is nothing that is available online or that can be shared here.
What could be the cause for this? If you need additional information just ask.
Generally, in order for an executable file (either an .EXE program or a .DLL support module) built using the MSVC C/C++ compiler in Visual Studio 2015 or later, to work on a target PC, you need to have the latest VC++ Redistributable run-time libraries installed on that PC.
See also this discussion on Stack Overflow.
Google gave me a clue that it is possible to compile code into a single executable that will run as 32bit on a 32bit OS and as 64bit on a 64bit OS. Is it really possible for the executable to determine its bitness at runtime?
In my case the target systems would be Windows 7 Professional x64 and Windows XP SP3 x86.
So what I read on various articles (I think there was even answers to similiar topics on SO) is that one has to go to the Soltuion's Configuration Manager (RMB onto Solution -> Configuration Manager) and set the Platform to Any CPU.
Now all of these articles described a setup for older MSVS or MSVC++ versions, but I think there are no major changes to the Configuration Manager in the 2013 RC version (which I have just recently installed).
In the Active Solution dropdown I do not have the option Any CPU, so I followed this recipe that I found on SO. Following this little guide fails in my case, I still do not have the option to select Any CPU when following step 5:
5) Make sure "Any CPU" is selected under New Platform. If there was
no Any CPU solution platform in step 3, then make sure the "Create
new solutions platform" checkbox is checked. Then click OK.
The dropdown items that are available to me are x64 and ARM (Win32 too but that is already added by default), I can not chose Any CPU.
Adding target platform x64 and compiling the executable works fine, the program is ran as 64bit on Windows 7 x64 but ofcourse it can not be run on the 32bit Windows XP machine.
How do I set the target platform to Any CPU in Microsoft Visual Studio Professional 2013 RC?
No it is absolutely not. You need to define separate executables.
The "Any CPU" dropdown is there to allow you to set compiler settings for more than one platform (e.g. a _DEBUG processor for x64 and Win32) You cannot actually build to that target.
AnyCPU refers to .Net programs, not C++. C++ must compile down to native, either x86 or x64. You could build 64 bit program and bundle it into your 32 program, extracting it at runtime. This technique is used by ProcessExplorer.
Perhaps not a true answer, but for MOST things, running 32-bit code on a 64-bit system works absolutely fine. Of course, it may run a little slower, but compared to having to deal with (and thoroughly test) two different binaries, unless it's significant performance benefits in 64-bit mode (or your application uses more than around 2GB of memory space), I'd be very tempted to use 32-bit mode.
MacOS supports something called "fat binaries", where the program is compiled twice and both versions are packed into a single file. The OS decides which version to actually launch.
Windows doesn't have anything like it.
You can compile the .NET wrapper (Any CPU) and the rest of program as yourprogram86.dll and yourprogram64.dll
[DllImport("yourprogram32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "open")]
public static extern void open32();
[DllImport("yourprogram64.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "open")]
public static extern void open64();
static bool Is64()
{
//.Net 4.0
//Environment.Is64BitOperatingSystem
//.Net 2.0
return IntPtr.Size == 8;
}
static void open()
{
if (Is64())
open64();
else
open32();
}
My C++ IDE is Visual Studio 2012 Express Version, and my Python IDE is Aptana3 (64-bit). My computer is Windows 7 64-bits.
I've write a .dll with C++ (Win32 console application), which basically follows the instruction at MSDN. It works well when I call it with a C++ application.
Then I try to call it from Python by following codes:
import ctypes
d = ctypes.WinDLL("C:\\DynamicLibrary\\Debug\\MathFuncsDll.dll")
However, I've got following error:
File "`<pyshell#8>`", line 1, in <module>
d = ctypes.WinDLL("C:\\DynamicLibrary\\Debug\\MathFuncsDll.dll")
File "C:\Python27\lib\ctypes\__init__.py", line 365, in __init__
self._handle = _dlopen(self._name, mode)
WindowsError: [Error 193] %1 is not a valid Win32 application
I've googled about this error message, and some posts say it because the compatibility between 32- and 64-bits. But I doubt it, since my IDE's and system are all 64-bit.
May I know what am I wrong?
Many thanks in advance. :)
The most common explanation for that error is that the system is attempting to load a 32 bit DLL into a 64 bit process, or vice versa. The fact that your system is 64 bit just makes that diagnosis more likely. Perhaps your Python is 64 bit, but the C++ project outputs a 32 bit DLL. Or vice versa.
In the question you state that your Python installation is 64 bits. In which case you need to look at your C++ project. What platform are you targetting? Win32 or x64? My money is on the answer to that question being that you target Win32.
That's the most likely explanation. Beyond that the next most likely cause is the exact same problem, but for one of the dependencies. The Python process and the DLL match, but when resolving the dependencies of the DLL the loader finds a DLL of the wrong bitness.
I've googled about this error message, and some posts say it because
the compatibility between 32- and 64-bits. But I doubt it, since my
IDE's and system are all 64-bit.
Yes, your research is correct.
My C++ IDE is Visual Studio 2012 Express Version,
My computer is Windows 7 64-bits.
That doesn't guarantee that you would build a 64 bit binary. Infact, VS 2012 IDE is a 32 bit application. Its the compiler and the CRT which is responsible to generate a 64 bit binary. And moreover the default settings for Visual Studio is to generate a 32 bit binary
You can easily google and determine how to build a 64 bit binary using Visual Studio. Alternatively, refer the link How to: Configure Visual C++ Projects to Target 64-Bit Platforms
and my Python IDE is
Aptana3 (64-bit). My computer is Windows 7 64-bits.
That still doesn't say anything about your Bitness of your Python Installation .
When in doubt, check for the bitness of your dll and your python.exe. You can easily determine the bitness using dumpbin
C:\Python27>dumpbin /headers python.exe|grep "machine"
14C machine (x86)
Build your C code to X64 version
I tested it and actually works well
I have been working on a VS 2005 project and have successfully generated an exe file which works fine on my system. However when I tried to run it on some other pc it didnt run. It throws up the error message "the system cannot run the specified program". Can someone tell me how to make my code immune to such message i.e. system independent?
platform used: Windows XP, VS 2005
the extension of all my code files is cpp but I know only c and thats what I wrote inside them.
I have seen before exe created on Windows Sp1 not working on SP2 and problems such as that.
This should help you perhaps.
I've seen this when you run on a different version of Windows that doesn't have some DLL you depend on. The easiest thing to do is statically link the C runtime (that's the usual culprit) and use depends.exe to see if there are any others.
You will almost certainly need to create an installer that installs your executable and any non-OS-included DLL's it relies upon. It is not always possible or desirable to statically link all dependencies. You can in many cases simply copy the DLL's to the same folder as the executable.
By default, even the C/C++ standard library is provided by a DLL. While the MSVCRT.DLL used by VC++ 6 is included with the OS since later editions Win95, the MSVCRT required by VS2005 is not included with XP installations (other versions I do not know). The run-time support is included VC redistributes package. You may need to arrange for your installer to include that installation, or you could be more selective is you know your dependencies.
Some Win32 API calls if you are using them are dependent on the OS version (check the documentation), but if you built and rin it on XP, it should normally work of any subsequent version of Windows. You need to define various API version macros if you want to extend support to earlier versions of Windows (which seems unlikley).
You might need to install the VS 2005 redistributables on the other machines, depending on how you have compiled your program.
Here's my configuration:
Computer A - Windows 7, MS Visual Studio 2005 patched for Win7 compatibility (8.0.50727.867)
Computer B - Windows XP SP2, MS Visual Studio 2005 installed (8.0.50727.42)
My project has some external dependencies (prebuilt DLLs - either build on A or downloaded from the Internet), a couple of DLLs built from sources and one executable. I am mostly developing on A and all is fine there. At some point I try to build my project on computer B, copying the prebuilt DLLs to the output folder. Everything builds fine, but trying to start my application I get
The application failed to initialize properly (0xc0150002)....
The event log contains two of those:
Dependent Assembly Microsoft.VC80.CRT could not be found and Last Error was The referenced assembly is not installed on your system.
plus the slightly more amusing
Generate Activation Context failed for
some.dll. Reference error message: The
operation completed successfully.
At this point I'm trying my Google-Fu, but in vain - virtually all hits are about running binaries on machines without Visual Studio installed. In my case, however, the executables fail to run on the computer they are built.
Next step was to try dependency walker and it baffled me even more - my DLLs built from sources on the same box cannot find MSVCR80.DLL and MSVCP80.DLL, however the executable seems to be alright in respect to those two DLLs i.e. when I open the executable with dependency walker it shows that the MSVC?80.DLLs can be found, but when I open one of my DLLs it says they cannot. That's where I am completely out of ideas what to do so I'm asking you, dear stackoverflow :)
I admit I'm a bit blurry on the whole side-by-side thing, so general reading on the topic will also be appreciated.
Your question has the answer to your problem: Computer A has VC runtime of version 8.0.50727.867, and Computer B has only version 8.0.50727.42.
You built your libraries on Computer A, and they depend on version 867 of VC runtime. (This can be found in manifest embedded in the libraries.) When you copy them to Computer B, these libraries still require version 867 of the runtime but you have only version 42.
To resolve the VC runtime assembly dependencies, you have to install VC runtime redistributables of version 867 on Computer B. However, I'd advise you to update Visual Studio on Computer B so that you have the same version on both computers. And even better, install Visual Studio 2005 SP1 on both computers and then install this security update to SP1. After installing the latter, your libraries will depend on version 8.0.50727.4053.
it's possible the problem is related with different versions of CRT runtime installed on both machines. is it possible to build all your modules to use statically linked CRT runtime to verify this?
first I'd check that prebuilt dlls by preparing dummy project to load them
I recently had the same type of error when building projects on one machine and then moving them to another machine. The biggest culprit here is likely a debug configuration for one of the binary components. That is, MSVC has the fairly rigid requirement of all DLLs/EXEs being built with the same runtime library, debug or release, otherwise they will not work together.
When I had this happen they also tend to compile just fine, but when you attempt to run them you get that extremely cryptic error message.
You need to ensure that every module you build together uses the same configuration, thus debug or release through the entire build chain. This error also likely comes up with mismatches in other libraries, so make sure your MSVC is the exact same version on the machines where you are building.