Inexplicable error 193 with LoadLibrary of a C++ DLL using \clr - c++

We have an user interface developped in C++ using Boost 1.54.0 and QT 4.8.6.
This interface can call computation module. Each module must implement a (non pure) abstract class and be linked to a given .lib generated during interface compilation. After launching the interface, we indicate the path of the module dll which is loaded using QLibrary.
Everything worked perfectly with native C++ module but recently we started developping new modules using .NET 3.5 (C#). We want the interface can call this module so we decided to create an intermediate c++ project using \clr : this project implements the abstract class and can call managed .NET code thanks to \clr mode.
Now we have a big problem : we cannot achieve to load correctly the intermediate C++ problem. We tried with the kernel32 method LoadLibrary and we obtained an error code 193 (ERROR_BAD_EXE_FORMAT). It is very surprising because all the projects are compiled for Win32/x86 and the computer is using a Windows Vista 32 bits.
Everything seems normal with dependancy walker :
We used dumpbin but everything seemed normal :
Microsoft (R) COFF/PE Dumper Version 9.00.30729.01 Copyright (C)
Microsoft Corporation. All rights reserved.
Dump of file Lien.dll
PE signature found
File Type: DLL
FILE HEADER VALUES
14C machine (x86)
6 number of sections
53CF72B5 time date stamp Wed Jul 23 10:30:45 2014
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
2102 characteristics
Executable
32 bit word machine
DLL

Thank you for the link Patrice Pezillier.
The issue was resolved by using your link : boost was the culprit.

Related

Is it not possible to run compiled C++ applications in Windows 95 and Windows NT 4.0?

Whenever I use MinGW to compile C++ applications, they work correctly in modern versions of Microsoft Windows including Windows 2000 and Windows XP.
However, when I attempt to run them on Windows 95 and Windows NT 4.0, I get these errors:
Does that mean that the idea of running compiled C++ applications is fundamentally unsupported in those versions?
Note: I haven't tested Windows 98 and Windows ME yet.
Edit: I've tested Windows 98. The testsortingvisualization runs properly, but the tetrisimplementation displays a blank command prompt and doesn't halt. Both of these programs gave the exact same error given above in Windows 95 and Windows NT 4.0. Keep in mind, Windows 2000 can run both correctly.
Edit:
Microsoft claims some of the functions I used (WriteConsoleOutput, GetAsyncKeyState) have a minimal requirement of Windows 2000. Indeed, it's tested not to work in Windows 98. I haven't figured out a more compatible way to do console output (system 8-bit codepage, 80 columns, 25 rows, 16 colors) or key detection.
The MSVCRT.DLL failure: the DLL is a critical dependency for compiled C++ applications, so it's fundamentally not possible to run any compiled C++ applications on Windows 95 at all.
I haven't found an explanation for the NT 4.0 issue.
When compiling, the compiler doesn't seem to find the correct definitions for a specific Windows version or a specific Internet Explorer version. Why is that?
You need to set defines _WIN32_WINDOWS, _WIN32_WINNT, WINVER and/or _WIN32_IE to the minimum platform you plan to support before including the windows.h header file. Possible values for these definitions can be found in the header w32api.h file.
Taken from here
The MS Visual C++ runtime DLL was not distributed with early versions of Windows, you either statically linked the code to the Microsoft libraries (not possible with MinGW), or you deploy the dependencies with your application.
The redistributable parts of VC++ (in which MSVCRT.DLL is included) are provided in a redistributable package specific to various versions of VC++, MSCVRT.DLL is from VC++ 6.0, and no longer available from from official sources; at your own risk you can get it from here for example.
Your Windows NT 4.0 error is a matter of your code using an API that was not part of the Win32 API when NT 4 was current. You can specify the target Windows version through various macros to restrict the API available to your code. That will then generate a compile time error rather then a runtime error. If that particular call is critical to your application, then it simply cannot be run on WinNT. The documentation for SetCriticalSectionSpinCount() states that the minimum supported system is XP.
With respect to your console I/O issue, MSVCRT.DLL includes Microsoft's conio library (not the same or as extensive as Borland's). MinGW includes conio.h header I think or here. That may provide what you need.
I could write novel here on the actual set of issues, but the bottom line is this:
Newer C/C++ runtime libraries, whether linked statically or dynamically into the target EXE, depend on OS APIs that were not available in Windows 9x. You'll need a set of tools that are still compatible with these a̶n̶c̶i̶e̶n̶t legacy versions of Windows.
You are going to need Visual Studio 2005 or earlier if you want to target Windows 95 and NT 4. As per the Wikipedia page:
Visual Studio 2005, codenamed Whidbey ... was released online in
October 2005 ... ... It is the last
version available for Windows 2000 and also the last version to be
able to target Windows 98, Windows Me and Windows NT 4.0 for C++
applications.
You might be able to do some hybrid thing with MinGW - let it still be the compiler, but link with the older MSVC*.lib files from Visual Studio 2005.
Perhaps you can statically link to the required libraries?

.Net DLL vs C++ DLL

How to differentiate between .NET DLL and C++ dll without looking at the code. Can we identify it by looking at the export table or other section of DLL after looking into DLL from any PE file explorer?
You might be able to use corflags
For a .NET c# DLL I get
Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 4.0.30319.1
Copyright (c) Microsoft Corporation. All rights reserved.
Version : v4.0.30319
CLR Header: 2.5
PE : PE32
CorFlags : 1
ILONLY : 1
32BIT : 0
Signed : 0
For a C++ DLL I get
corflags : error CF008 : The specified file does not have a valid managed header
**** UPDATE ****
I might have misunderstood the question. This is a good SO question on a similar problem. How can I test a Windows DLL file to determine if it is 32 bit or 64 bit?
As a matter of fact, this is clearly indicated by looking at the Image file and is documented by the Portable Executable format specification. Should the Directory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR] be present (not EMPTY), the image is Managed (.NET) otherwise the image is unmanaged.

Missing msvcr100.dll error while running an executable built with MinGW

I am successfully compiling (with MinGW) and running my C++ program (which calls Java classes through JNI) consisting of multiple files on my Win7-64bit system. Compiling and running is done by 2 batch files. I installed Visual Studio C++ 2010 some time ago but haven't used it since.
I am now trying to deploy this program to another computer running WinXP-32bit and I am facing a "missing msvcr100.dll" error. I installed the latest MinGW and JDK, I compiled my program using the same batch file, but when I'm running it, I get the error. Visual Studio is not used in any part of the building (and I don't want it to), so I find it strange that I get this message about an MSVC++ dll.
compile.bat
rem Set the include paths for the JNI header files("include" and "include\win32" inside the jdk (32-bit) directory).
set JDK_INCLUDE="C:\Program Files\Java\jdk1.7.0\include"
set JDK_INCLUDE_WIN32="C:\Program Files\Java\jdk1.7.0\include\win32"
set PATH=%PATH%;C:\MinGW\bin
rem Build an import library for the jvm.dll from the .\lib\jvm.def file (see http://www.inonit.com/cygwin/jni/invocationApi/archive.html)
dlltool --input-def .\lib\jvm.def --kill-at --dllname jvm.dll --output-lib .\lib\libjvm.dll.a
rem Set the import library directory.
set JVM_IMPORT_DLL=".\lib"
rem Compile all files (including the IngToolTest.cpp) and create an executable file .\bin\COFORM_JNI.exe
g++ -I%JDK_INCLUDE% -I%JDK_INCLUDE_WIN32% .\src\DataTypes\file1.cpp .\src\IngestionTool\file2.cpp ... .\src\file25.cpp Test.cpp -L%JVM_IMPORT_DLL% -ljvm -o .\bin\executable.exe
pause
run.bat
Rem Set the environment parameter to the path where the properties file resides.
set CONFIG_DIR=..
Rem Set the environment parameter to the actual IP of your VM machine.
set VM_URL=139.191.173.43
Rem Set the location of the jvm.dll (32-bit)
set PATH=%PATH%;C:\Program Files\Java\jdk1.7.0\jre\bin\client
move *.rdf RDFS
.\bin\executable.exe
pause
Is it possible that one of my external includes is causing this? Here they are:
#include <stdio.h>
#include <cstdlib>
#include <iostream>
#include <jni.h>
#include <vector>
#include <string.h>
#include <fstream>
using namespace std;
I would appreciate any help to overcome this error.
K
While MinGW is a distribution of GCC, to allow it to run natively on Windows without having a Linux emulation layer like Cygwin it does not use the GNU C library. Instead it uses Microsoft's C Runtime. I have not used MinGW for a while, when it used MSVCRT.DLL from VC++ 6.0, which was more or less ubiquitous in Windows installations at the time as it shipped with installations since late Win95 editions.
It is quite possible that your installation of Windows does not have the later runtime if it was not distributed with it and you have not installed any application with which it was distributed. It may be that you have only the 64 bit DLL and need to install the 32 bit DLL.
The simple solution is to install Microsoft's VC++ re-distributable package(s).
Microsoft Visual C++ 2010 Redistributable Package (x64)
Microsoft Visual C++ 2010 Redistributable Package (x86)
Added Note: According to both http://mingw-w64.sourceforge.net/ and http://www.mingw.org, MinGW still depends on MSVCRT.DLL, so I wonder what you have done or where you obtained your distribution that makes it depend on MSVCRT100.DLL? Some experimental build perhaps?
The DLL contains the runtime for compiled programs. It must be installed on the other machine to be able to run the program.
Standard program distributions have an install package that does this for you, or you can install it manually.
See here for download instructions
http://www.microsoft.com/download/en/details.aspx?id=5555
MinGW merely emulates Linux OS calls. Let me explain..
When you ceate a binary that runs on a certain OS, that binary needs to know how to interact with the underlying OS. This is important for things like memory allocation. The binary doesn't natively "know" how to allocate RAM, instead, it asks the host OS to give it some RAM. It does this, by calling an allocation function that resides at a predetermined "address" inside the OS.
How does the application know what "address" the allocation method exists at?
When you compile the binary, you bind to it a "C runtime library (CRT)". This library contains all the mappings for OS interactions that the binary will need. So for example, when you link the CRT, the binary now knows where it can find the memory allocation function that is exposed by the OS.
MinGW, inserts an emulation layer such that an application thinks its linking to a Linux CRT, but really, the emulation layer just redirects calls to the Microsoft CRT.
Windows, has a number of different CRTs available. On all distributions, you can find somewhere in %PATH%, the file msvcrt.dll. This file, provides all support that a binary would need to run in the OS.
When you install Visual Studio, you get updated versions of the CRT:
In VS 2005: msvcrt80.dll
In VS 2008: msvcrt90.dll
In VC 2010: msvcrt100.dll
Apparently, by installing Visual Studio, you've caused MinGW's emulation layer to link against msvcrt100.dll, rather than the msvcrt.dll, that comes distributed on all windows machines. I don't know why this is happening, but this IS what is happening.
EDIT
The command:
dlltool --input-def .\lib\jvm.def --kill-at --dllname jvm.dll --output-lib .\lib\libjvm.dll.a
Which is producing a file that links in jvm.dll might creating the msvcrt100.dll dependency. That is, jvm.dll might be dynamically linked against the newest CRT, and because you require jvm.dll you indirectly need msvcrt100.dll.
Are there any dll's found in ""C:\Program Files\Java\jdk1.7.0\bin"?

tlibimp.exe output differs on different OSes

I'm trying to import a third-party .NET type library (COM server DLL) using tlibimp.exe (version 11.0). This basically works fine, but the results differ when I run it on different computers, one running Windows XP, the other Windows 7. What's worse, the code generated on the Win7 machine doesn't compile.
Both machines have:
Borland C++ (RAD Studio) 2007
tlibimp.exe version 11.0
the same .NET framework versions installed (as far as I can tell,
Borland 2007 uses .NET v2)
bcc32.exe version 5.93
The compiler fails in the OCX.h with:
Parameter mismatch in write access specifier of property Font
The relevant line of code on the XP machine (which compiles ok) is:
__property Graphics::TFont * Font={ read=GetTFontProp, write=_SetTFontProp, stored=false, index=-512 };
The same line on the Win7 machine (which fails) is:
__property IFontDisp* Font={ read=get_Font, write=set_Font, stored=false };
Now I'm not really sure where this difference comes from. Any ideas?
cheers
Hendrik
This may or may not help but I had a similar issue trying to import two type libraries into delphi, from c sharp assemblies.
One type library (A) inherited from TOLeServer, the other (B) from TOleControl and I couldn't see why, as both assemblies which generated the type libraries were virtually identical.
The issue turned out to be that B had been registered with regasm and A hadn't. Registering A and re-generating the type library solved the issue.

Windows API commctrl.h using application doesn't work on machines without the Platform SDK

I have written something that uses the following includes:
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <commctrl.h>
This code works fine on 2 machines with the Platform SDK installed, but doesn't run (neither debug nor release versions) on clean installs of windows (VMs of course). It dies with the quite familiar:
---------------------------
C:\Documents and Settings\Someone\Desktop\DesktopRearranger.exe
---------------------------
C:\Documents and Settings\Someone\Desktop\DesktopRearranger.exe
This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem.
---------------------------
OK
---------------------------
How can I make it run on clean installs? Which dll is it using which it can't find? My bet is on commctrl, but can someone enlighten me on why it's isn't with every windows?
Further more, if anyone has tips on how to debug such a thing, as my CPP is already rusty, as it seems :)
Edit - What worked for me is downloading the Redistributable for Visual Studio 2008. I don't think it's a good solution - downloading a 2MB file and an install to run a simple 11K tool. I think I'll change the code to use LoadLibrary to get the 2 or 3 functions I need from comctl32.dll. Thanks everyone :)
Use Dependency Walker. Download and install from http://www.dependencywalker.com/ (just unzip to install). Then load up your executable. The tool will highlight which DLL is missing. Then you can find the redistributable pack which you need to ship with your executable.
If you use VS2005, most cases will be covered by http://www.microsoft.com/downloads/details.aspx?FamilyId=32BC1BEE-A3F9-4C13-9C99-220B62A191EE&displaylang=en which includes everything needed to run EXEs created with VS2005. Using depends.exe you may find a more lightweight solution, though.
Common controls is a red herring. Your problem is that the Visual C++ 8.0 runtime - I assume you're using Visual Studio 2005 - isn't installed. Either statically link to the C/C++ runtime library, or distribute the runtime DLL.
You will have this problem with any C or C++ program that uses the DLL. You could get away with it in VS 6.0 as msvcrt.dll came with the OS from Windows 2000 up, and in VS.NET 2003 as msvcr71.dll came with .NET Framework 1.1. No more. Visual Studio 2005 and later use side-by-side assemblies to prevent DLL Hell, but that means you can't rely even on .NET 2.0 installing the exact version of C runtime that your program's built-in manifest uses. .NET 2.0's mscorwks.dll binds to version 8.0.50608.0 in its manifest; a VS-generated application binds to 8.0.50727.762 as of VS2005 SP1. My recollection is it used some pre-release version in the original (RTM) release of VS2005, which meant you had to deploy a Publisher Policy merge module if you were using the merge modules, to redirect the binding to the version actually in the released C run-time merge module.
See also Redistributing Visual C++ Files on MSDN.
I suspect it is trying to find a version of common controls that isn't installed. You may need a manifest file to map the version of common controls to your target operating system. Also, you may need to make sure you have installed the same VC runtimes that you were linked to.
Chris Jackson blog
EDIT: A little searching and I've confirmed (mostly) that it is the version of your VC++ runtimes that is to blame. You need to distribute the versions that you built with. The platform SDK usually includes a merge module of these for that purpose, but there is often a VCRedist.exe for them as well. Try looking Microsoft's downloads.
KB94885