Win32 DLL importing issues (DllMain) - c++

I have a native DLL that is a plug-in to a different application (one that I have essentially zero control of). Everything works just great until I link with an additional .lib file (links my DLL to another DLL named ABQSMABasCoreUtils.dll). This file contains some additional API from the parent application that I would like to utilize. I haven't even written any code to use any of the functions exported but just linking in this new DLL is causing problems. Specifically, I get the following error when I attempt to run the program:
The application failed to initialize properly (0xc0000025). Click on OK to terminate the application.
I believe I have read somewhere that this is typically due to a DllMain function returning FALSE. Also, the following message is written to the standard output:
ERROR: Memory allocation attempted before component initialization
I am almost 100% sure this error message is coming from the application and is not some type of Windows error.
Looking into this a little more (aka flailing around and flipping every switch I know of) I linked with /MAP turned on and found this in the resulting .map file:
0001:000af220 ??3#YAXPEAX#Z 00000001800b0220 f ABQSMABasCoreUtils_import:ABQSMABasCoreUtils.dll
0001:000af226 ??2#YAPEAX_K#Z 00000001800b0226 f ABQSMABasCoreUtils_import:ABQSMABasCoreUtils.dll
0001:000af22c ??_U#YAPEAX_K#Z 00000001800b022c f ABQSMABasCoreUtils_import:ABQSMABasCoreUtils.dll
0001:000af232 ??_V#YAXPEAX#Z 00000001800b0232 f ABQSMABasCoreUtils_import:ABQSMABasCoreUtils.dll
If I undecorate those names using "undname" they give the following (same order):
void __cdecl operator delete(void * __ptr64)
void * __ptr64 __cdecl operator new(unsigned __int64)
void * __ptr64 __cdecl operator new[](unsigned __int64)
void __cdecl operator delete[](void * __ptr64)
I am not sure I understand how anything from ABQSMABasCoreUtils.dll can exist within this .map file or why my DLL is even attempting to load ABQSMABasCoreUtils.dll if I don't have any code that references this DLL. Can anyone help me put this information together and find out why this isn't working? For what it's worth I have confirmed via "dumpbin" that the parent application imports ABQSMABasCoreUtils.dll, so it is being loaded no matter what. I have also tried delay loading this DLL in my DLL but that did not change the results.
EDIT
I have double checked and all files involved are 64 bit.

I just had exactly the same problem. This is an issue with the Abaqus API rather than with the loading of DLLS.
I think it is because the Abaqus API overrides the new and delete functions (as you seem to have noticed). If you call new or delete in your program before initializing the Abaqus API, such as by calling odb_initializeAPI(); then you get the
ERROR: Memory allocation attempted before component initialization
error message and the program crashes.
In my program, calling odb_initializeAPI(); before the first new resolved the problem.

Well, sure you'll reference the imports of that library. Hard to write a C++ program without using the new or delete operator. Dealing with 3rd party software that thinks it needs to override the CRT version of those operators is hard enough, impossible when it won't allow you to call them until it thinks the time is right. Abandon all hope or seek help from the vendor.

One of the possible reason of an error during loading of ABQSMABasCoreUtils.dll is that some dependency module (inclusive delayed load DLLs) could not be found. Use Dependency Walker (see http://www.dependencywalker.com/) to examine all dependencies of ABQSMABasCoreUtils.dll.
I have two suggestions:
Verify that you can load ABQSMABasCoreUtils.dll with respect of LoadLibrary. You don't need call any function from ABQSMABasCoreUtils.dll. Usage of LoadLibrary I don't see as the end solution. It' s only a diagnostic test. With the test you can verify either you have some general problem of loading ABQSMABasCoreUtils.dll in your program or you have some kind of process initialization problem.
If loading of ABQSMABasCoreUtils.dll with respect of LoadLibrary will failed, then use profiling feature of Dependency Walker to protocol of all calls done during loading of ABQSMABasCoreUtils.dll. One other way would be usage of Process Monitor (see http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx) to trace what file and registry operations will be done during loading of ABQSMABasCoreUtils.dll.
If LoadLibrary is not failed, then you have really an initialization problem of DLLs. Typically the problem exist if a DLL inside of DllMain try use a function from another DLL which is not yet initialized (not yet returns from DllMain). Before one start diagnostic of this problem, we should try to exclude a more simple problems with LoadLibrary.

The ABQSMABasCoreUtils.dll looks like it's importing 64-bit functions. Is your dll also 64-bit? If not, then that's the problem - you cannot mix DLLs compiled for different architectures in the same process.

Related

difference between Load DLL and Direct Call

i think is very stupid, but I can't understand,
for example, I want use Windows API like GetWindowsDirectory, GetSystemInfo and etc... I can use Api directly or calling through GetProcAddress :
Method 1
here I can calling APIs with LoadLibrary and GetProcAddress :
#include <windows.h>
typedef UINT (WINAPI *GET_WIN_DIR)(LPWSTR lpBuffer, UINT size);
TCHAR infoBuffer[MAX_PATH + 1];
HINSTANSE dllLoad = LoadLibrary("Kernel32.dll");
GET_WIN_DIR function = (GET_WIN_DIR )GetProcAddress(dllLoad, "GetWindowsDirectoryW");
int result = function2(infoBuffer, MAX_PATH + 1);
Method 2
here I can calling directly APIs like GetWindowsDirectory :
#include <windows.h>
TCHAR infoBuffer[MAX_PATH + 1];
GetWindowsDirectory(infoBuffer, MAX_PATH);
I have 2 question :
What is the difference between the two methods above?
is it load Library impact on executable file?(.exe)(I did test, but it'snot changed)
Microsoft calls
Method 1 ... Explicit linking
Method 2 ... Implicit linking
From MSDN Linking an Executable to a DLL:
Implicit linking is sometimes referred to as static load or load-time dynamic linking. Explicit linking is sometimes referred to as dynamic load or run-time dynamic linking.
With implicit linking, the executable using the DLL links to an import library (.lib file) provided by the maker of the DLL. The operating system loads the DLL when the executable using it is loaded. The client executable calls the DLL's exported functions just as if the functions were contained within the executable.
With explicit linking, the executable using the DLL must make function calls to explicitly load and unload the DLL and to access the DLL's exported functions. The client executable must call the exported functions through a function pointer.
An executable can use the same DLL with either linking method. Furthermore, these mechanisms are not mutually exclusive, as one executable can implicitly link to a DLL and another can attach to it explicitly.
In our projects we use implicit linking in any common case.
We use the explicit linking exceptionally in two situations:
for plug-in DLLs which are loaded explicitly at run-time
in special cases where the implicit linked function is not the right one.
The 2nd case may happen if we use DLLs which themselves link to distinct versions of other DLLs (e.g. from Microsoft). This is, of course, a bit critical. Actually, we try to prevent the 2nd case.
No, I don't think it's stupid at all. If you don't understand, ask. That's what this site is for. Maybe you'll get downvoted, who knows, but not by me. Goes with the territory. No pain, no gain, ask me how I know.
Anyway, the main purpose of what #Scheff calls 'explicit linking' is twofold:
If you're not sure whether the the DLL you want to use to is going to be present on the machine at runtime (although you can also use /DELAYLOAD for this which is a lot more convenient).
If you're not sure if the function you want to call is present in (for example) all versions of Windows on which you want your application to run.
Regard point 1, an example of this might be reading or writing WMA files. Some older versions of Windows did not include WMA support by default (we're going back quite a long way here) and if you implicitly link to WMA.DLL then your application won't start up if it's not present. Using explicit linking (or /DELAYLOAD) lets you check for this at runtime and put up a polite message if it's missing while still allowing the rest of your app to function as normal.
As for point 2, you might, for example, want to make use of the LoadIconWithScaleDown() function because it generally produces a nicer scaled icon than LoadIcon(). However, if you just blindly call it then, again, your app wont run on XP because XP doesn't support it, so you would instead call it conditionally, via GetProcAddress(), if it's available and fall back to LoadIcon() if not.
Okay, so to round off, what's the deal with /DELAYLOAD? Well, this is a linker switch that lets you tell the linker which DLL's are optional for your app. Once you've done that, then you can do something like this:
if (LoadIconWithScaleDown)
LoadIconWithScaleDown (...);
else
LoadIcon (...);
And that is pretty neat.
So I hope you can now see that this question is really about the utility of explicit linking versus the inconvenience involved (all of which goes way anyway with /DELAYLOAD). What goes on under the covers is, for me, less interesting.
And yes, the end result, in terms of the way the program behaves, is the same. Explicit linking or delay loading might involve a small (read: tiny) performance overhead but I really wouldn't worry about that, and delay loading involves a few potential 'gotchas' (which won't affect most normal mortals) as detailed here.

MSVCR and CRT Initialization

Out of curiosity, what exactly happens when an application compiled with the MSVCR is loaded, resp. how does the loader of Windows actually initialize the CRT? For what I have gathered so far, when the program as well as all the imported libraries are loaded into memory and all relocations are done, the CRT startup code (_CRT_INIT()?) initializes all global initializers in the .CRT$XC* sections and calls the user defined main() function. I hope this is correct so far.
But let's assume, for the sake of explanation, a program that is not using the MSVCR (e.g. an application built with Cygwin GCC or other compilers) tries to load a library at runtime, requiring the CRT, using a custom loader/runtime linker, so no LoadLibrary() involved. How would the loader/linker has to handle CRT initialization? Would it have to manually initialize all "objects" in said sections, does it have to do something else to make the internal wiring of the library work properly, or would it have to just call _CRT_INIT() (which unpractically is defined in the runtime itself and not exported anywhere as far as I am aware). Would this mix-up even work in any way, assuming that the non-CRT application and the CRT-library would not pass any objects, exceptions and things the like between them?
I would be very interested in finding out, because I can't quite make out what the CRT has an effect on the actual loading process...
Any information is very appreciated, thanks!
The entrypoint for an executable image is selected with the /ENTRY linker option. The defaults it uses are documented well in the MSDN Library article. They are the CRT entrypoint.
If you want to replace the CRT then either pick the same name or use the /ENTRY option explicitly when you link. You'll also need /NODEFAULTLIB to prevent it from linking the regular .lib
Each library compiled against the C++ runtime is calling _DllMainCRTStartup when it's loaded. _DllMainCRTStartup calls _CRT_INIT, which initializes the C/C++ run-time library and invokes C++ constructors on static, non-local variables.
The PE format contains an optional header that has a slot called 'addressofentrypoint', this slot calls a function that will call _DllMainCRTStartup which fires the initialization chain.
after _DllMainCRTStartup finishes the initialization phase it will call your own implemented DllMain() function.
When you learn about programming, someone will tell you that "the first thing that happens is that the code runs in main. But that's a bit like when you learn about atoms in School, they are fairly well organized and operate acorrding to strict rules. If you later go to a Nuclear/Particle Physics class at university, those simple/strict rules are much more detailed and don't always apply, etc.
When you link a C or C++ program the CRT contains some code something like this:
start()
{
CRT_init();
...
Global_Object_Constructors();
...
exit(main());
}
So the initialization is done by the C runtime library itself, BEFORE it calls your main.
A DLL has a DllMain that is executed by LoadLibrary() - this is responsible for initializing/creating global objects in the DLL, and if you don't use LoadLibrary() [e.g. loading the DLL into memory yourself] then you would have to ensure that objects are created and initialized.

Encountering errors when using C++ interop on old MFC/Win32 application

I have inherited an old MFC/Win32 C++ application who's source code I am not supposed to edit.
This MFC application needs to host an old MFC/Win32 C++ DLL. This DLL also tries to make function calls through a Mixed-mode wrapper to a managed C++/CLI DLL. I know it sounds a little confusing, so here's a diagram of what I mean:
Old MFC/Win32 Application (NO CLR)
---> Hosting old MFC/Win32 DLL (NO CLR)
---> Making function calls to Mixed-Mode wrapper (CLR)
---> Sending function calls to C++/CLI DLL (CLR)
My problem currently is that when I try to mount an object of the C++/CLR wrapper class let's say WrapperClass WC;, the MFC/Win32 application encounters an "Unhandled exception."
I have a feeling that I may need to somehow host the CLR in a separate process in order to be able to make the object. Is this the right idea? Or am I completely out of whack here?
The code compiles time and this only occurs at run-time.
Any ideas?
Here is an example of the code I am trying to run:
MFC/Win32 DLL
#include "WrapperClass.h"
BOOL Test::bTest() //This function is called elsewhere within MFC/Win32 DLL
{
DWORD dwTest;
WrapperClass WC; //Unhandled exception here!
return WC.FunctionToCall(dwTest); //FunctionToCall is a BOOL
}
Mixed-Mode Wrapper Class
BOOL WrapperClass::FunctionToCall(DWORD dw)
{
GCHandle h = GCHandle::FromIntPtr(IntPtr(m_impl)); //m_impl def'd as void *
CPPCLIClass^ CCC = safe_cast<CPPCLIClass^>(h.Target);
return (BOOL)CCC->FunctionToCall(dw);
}
C++/CLI DLL
bool CPPCLIClass::FunctionToCall(UInt32 ui32)
{
if (ui32 == 42)
{
return true;
}
}
UPDATE:
I've managed to coax a real exception out of the program. I am now receiving a System.IO.FileNotFound exception with additional information stating:
An unhandled exception of type 'System.IO.FileNotFoundException' occured in
Unknown Module.
Additional information: Could not load file or assembly 'CPPCLIProject,
Version=1.0.4351.29839, Culture=neutral, PublicKeyToken=null' or one of its
dependencies. The system cannot find the file specified.
Does this mean anything? I understand that it apparently cannot find CPPCLIProject (Note: this is not the wrapper project), but then if I'm linking on the .lib file from the Mixed-mode wrapper, how would I not receive linker errors then?
Are you sure that the implementation of WrapperClass::FunctionToCall() isn't throwing the exception? It looks like you're caching the memory location of a CLR object, and then trying to call one of its members. I think the CLR is free to move objects around, so it's possible that you're trying to use an object that has moved.
If you change the implementation of WrapperClass::FunctionToCall() to something simple (i.e. create a CLR object, call a member function), do you still get the same unhandled exception?
UPDATE: Which class is in CPPCLIProject - CPPCLIClass? Assuming this project represents the C++/CLI DLL, it sounds like it just can't find the assembly to load it when it needs to call your class.
Where is this assembly on disk relative to the rest of the application? If your root EXE is unmanaged (which it sounds like it is, since it is MFC/Win32), then the CLR looks in the EXE's directory and the GAC in order to load assemblies (I don't think it looks in the Path, but I'm not positive on that).
So if the CPPCLIProject isn't in the same directory as the EXE, that could be your problem.
Your best bet is to
run under a debugger (add the additional DLLs with debug information to the debug session)
enable break on all (first-chance) exceptions
trace/assert all HRESULT codes
in general try to catch
C++ exceptions (try/catch...)
Windows Structured Exceptions (IIRC _try/_catch, but see MSDN)
The idea is to convert the 'unkown exception' into 'known exception'.
Normally speaking there is no need to host the CLR part out of process. This is what a mixed-mode DLL is about. Then again, if this is legacy code, you might be running into complicated mixes of runtime dependencies that, shall we say, could clash.
Further thoughts:
If I understand correctly, you have the option to recompile all sources (just not touch the legacy codebase?). If so, make sure all code is compiled against the same version (think Service Packs) and type (think Static vs Dynamic/Multithread/Debug) of the runtime libraries.
While you are checking additional pathways, keep an eye on potentially conflicting dependencies on
ATL server libs
MFC libs (again static vs dynamic/Multithread/Debug flavours).

Calling a Visual Basic DLL in C++

I have acquired a DLL that was created in Visual Basic from a third party vendor(Sensor DLL.dll). This DLL contains functions for talking to a sensor, and I need to call these functions from a Visual C++ program I am writing. The vendor will not provide a header file, and I do not know Visual Basic. If I had a header file this would be a 15 minute project... instead I am still struggling with it a week later. Please Help!
I am told one function (Get_Data) in the DLL is of the form:
Public Function Get_Data(ByVal Handle As String) As String
I have tried several methods for calling this Get_Data function with no success:
Method 1) the DllImport attribute
#using <mscorlib.dll>
using namespace System::Runtime::InteropServices;
namespace Sensor
{
[DllImport("Sensor DLL.dll", EntryPoint = "Get_Data", CharSet = System::Runtime::InteropServices::CharSet::Unicode)]
BSTR Get_Data(BSTR Handle);
}
//then I call the function
Sensor::Get_Data(Handle);
This method seems to be the closest I have gotten to a sloution. It compiles, but gives the following error when it runs:
An unhandled exception of type 'System.EntryPointNotFoundException' occurred
Additional information: Unable to find an entry point named 'Get_Data' in DLL 'Sensor DLL.dll'.
I have tried various datatype combinations/permutations besides BSTR including BSTR*, wchar_t, int, etc. It is possible that I missed one, but each datatype returns the same error.
Method 2) dllimport storage-class attribute
__declspec(dllimport) BSTR Get_Data(BSTR Handle);
//then I call the function
Get_Data(Handle);
This method is confusing to me because I don't specify the DLL I want to import from. I have copied the DLL to the project folder and I have added it to the project manually, so hopefully that means it can be found. When I compile the linker returns the following errors:
error LNK2028: unresolved token (0A00034F) "wchar_t * __cdecl Get_Data(wchar_t *)" (?Get_Data##$$FYAPA_WPA_W#Z) referenced in function "int __cdecl main(void)" (?main##$$HYAHXZ)
error LNK2019: unresolved external symbol "wchar_t * __cdecl Get_Data(wchar_t *)" (?Get_Data##$$FYAPA_WPA_W#Z) referenced in function "int __cdecl main(void)" (?main##$$HYAHXZ)
I suspected maybe this meant I should be using wchar_t or wchar_t* instead of BSTR, but changing to either datatype results in the same error.
Method 3) GetProcAddress
typedef BSTR (*Get_Data_Ptr)(BSTR Handle);
HINSTANCE LoadMe;
LoadMe = LoadLibraryA("Sensor DLL.dll");
if (!LoadMe)
std::cout << "\nDLL failed to load!\n";
Get_Data_Ptr LibMainGet_Data;
LibMainGet_Data = (Get_Data_Ptr)GetProcAddress(LoadMe,"Get_Data");
//then I call the function
LibMainGet_Data(Handle);
This will compile, but gives the following error when run:
An unhandled exception of type 'System.AccessViolationException' occurred
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
When I mouse over the various parts of this code in debug mode it seems that, like the first method, it was also unable to find the 'Get_Data' entry point in the DLL.
Has anyone called functions from a VB DLL using C++ when you haven't made the DLL yourself and you don't have .idl files, etc? Does anyone have a working example like this you could share?
Thanks!
A VB6 DLL is normally a COM server. You do in fact have the equivalent of a .h file, it has a type library embedded in it. Start this off with Project + Properties, Common Properties, Framework and References. Add New Reference button, Browse tab, select the DLL.
Next, View + Object Browser. You should see the generated Interop library in the list. Open the node to see what is there. You write normal managed code, like gcnew, to create the COM object and call the interface methods. You do need some minimum documentation on the available methods to have a guess at how they should be called.
I believe the missing piece is the calling convention. C++ has its own function calling convention different than VB6 (I assume VB6 since you haven't stated VB.NET explicitly). VB6 uses STDCALL convention whereas C++, depending on the vendor, uses a different calling convention termed __cdecl, which is why you see the __cdecl in the compiler error line for method #2. It assumes your external function is using that calling convention by default. Calling convention is a set of rules describing how functions call one another; specifically about how registers are used, what order parameters are delivered in, how by-value / by-reference is determined, etc.
I would suggest sticking with method #3 since method #1 is for Managed C++ which is not standard C++, and method #2 is unfamiliar to me and looks a bit ambiguous. What you want to try is declaring the function pointer typedef to use STDCALL.
typedef BSTR (__stdcall *Get_Data_Ptr)(BSTR Handle);
In the OLE/COM viewer, in order to view the COM type library in a dll/exe/... you have to open it by using "File->View TypeLib" instead of "File->Bind to File"
It sounds like the DLL isn't actually exporting a function named Get_Data. Open up a command prompt and use dumpbin to get the list of exports of the DLL, e.g.:
dumpbin /exports "Sensor DLL.dll"
(dumpbin.exe is located in VC\bin within your Visual Studio install folder, which istypically something like C:\Program Files\Microsoft Visual Studio 10.0).
Then, replace Get_Data with the actual entry point and see if you have any better luck.
A Visual basic program normally needs a runtime to execute.
If you have a COM object (implemented in VB) use the COM API to communicate with it from C++. You will have to register the COM first. Here is a thread that explains hot to do that: http://forums.devx.com/archive/index.php/t-87059.html
If you use a .NET language, use the method of Hans Passant with a reference that will create an interop dll for you. This is far much easier.
Method 1: Do not do that, if you have a COM object that you want to use from a .NET environment, reference it.
Method 2: You get errors because you lack the the .lib file to properly link to the DLL (statically dynamically linking)
Method 3: Would be a pure dynamic solution but you have to know the exact names of the methods in the DLL. These may vary according to the parameters and calling convention used. This is very similar (actually identical, I would say) to the issue you face with your Method 1 solution. The name of the method is for yure not "Get_Data" but something else. With a tool like the dependency viewer you can have a look at the exported names.
Even Method 3 with the right names is likely to fail because if it is a COM object you will need some environment called Appartment to use the COM objects. You "enter" this appartment by calling CoInitialize. This creates some magical stuff in the TLS (Thread Local Storage) to perform the COM magic. I hope this explains why your tries will be pointless if the DLL you have is happening to be a COM component, what is quite likely according to the ATL like naming we can see.
EDIT:
I forgot to say that you can also easily see what is inside the dll if it is a COM with the OLE/COM Viewer (normally if you have a compiler you will have such a tool around).

The LoadLibraryA method returns error code 1114 (ERROR_DLL_INIT_FAILED) after more than 1000 cycles of loading/unloading

I'm programing on C++, I'm using Visual Studio 2008, Windows XP, and I have the following problem:
My application, that is a DLL that can be used from Python, loads an external dll, uses the required methods, and then unloads this external Dll.
It's working properly, but after more than 1000 cycles the method "LoadLibraryA" returns a NULL reference.
The main steps are:
HINSTANCE h = NULL;
h = LoadLibraryA(dllfile.c_str());
DWORD dw = GetLastError();
The error got is:
ERROR_DLL_INIT_FAILED
1114 (0x45A) A dynamic link library (DLL) initialization routine failed.
The Dll is unloaded by using the following:
FreeLibrary(mDLL);
mDLL = NULL;
Where mDLL is defined like this:
HINSTANCE mDLL;
First alternative tried:
Just load the Dll only once, and unloaded it when the application ends. This fix the problem but introduces a new one.
When the application ends, instead of first executing the DllMain method of my applicaion, wich unloads the external DLL, is executing first the DllMain method of the other Dll. This cause the following error because my application is trying to unload a Dll that was unload by itself previously.
"Unhandled exception at 0x04a00d07 (DllName.DLL) in Python.exe: 0xC0000005: Access violation reading location 0x0000006b".
Any suggestion will be welcomed.
Thanks in advance.
Regards.
Make sure that initialization code of the loaded/unloaded library doesn't leak memory. Many libraries expect to be loaded only once and not always clean up their resources properly.
E.g. in C++ file at the top level one can declare and initialize a variable like this:
AClass *a = new AClass(1,2,3);
The code would be executed when library is loaded automatically. Yet, now, it is impossible to free the hanging instance as library doesn't know precisely when/how it is going to be unloaded. In the case one can either replace "AClass *a" with "AClass a" or write your own DllMain for the library and free resources on DLL_PROCESS_DETACH.
If you have no control over the library's code, then it might make sense to create a cache of loaded libraries and simply never unload them. It is very hard to imagine that there would be unlimited number of libraries to overload such cache.