Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Win32 DLL importing issues (DllMain)

Tags:

c++

winapi

abaqus

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.

like image 450
brady Avatar asked May 27 '10 23:05

brady


3 Answers

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.

like image 52
David Dibben Avatar answered Nov 11 '22 23:11

David Dibben


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.

like image 43
Hans Passant Avatar answered Nov 12 '22 00:11

Hans Passant


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:

  1. 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.
  2. 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.

like image 1
Oleg Avatar answered Nov 12 '22 01:11

Oleg