Click here to Skip to main content
14,297,338 members
Rate this:
Please Sign up or sign in to vote.
See more:
Hello , once again i need some help.
So i have few dlls in one solution each of them exports some functions , which are declared with
extern "C" <type> __stdcall <name>(<params>)
and each of them uses .def file for the exports.
The pointers are
typedef <type> (CALLBACK * <name> )(<type of params>)


The problem is with one of the dlls , which are loaded with LoadLibrary.
I know the signatures of the functions ,i use GetProcAddress() , i used the right number and types of paramethers , no errors are thrown but the functions of the dll arent't executed. The other which are using the same methods of creating function pointers and using them described above are working properly.

Because i have some old versions of the dlls i used dumpbin /export and i saw something strange.
In the older version of the dll there is a

name of the function = @ILT+some number(_name of the function@number)

and for the new dll i see only <name of="" the="" function=""> without the rest
I know that the function pointer should get that _name of the function @ number which is some encoding of the function's name in the memory but it doesn't.

I think maybe i did something wrong with the creation of the dll maybe a option or something but i have no idea what .
Any ideas are welcome.
Thanks a lot for the help ... again :)

P.S
When i checked the dll with dumpbin /headers i noticed that 2 header sections are missing : .idata and .textbss can someone give me more info about what exactly is a header in a dll and how should it be created

P.S 2
 HMODULE hDllHandle = LoadLibrary(TEXT(strDllName));
 if (hDllHandle != NULL)
 {
      //declarations of few local variables  
      
     PFuncA  pFunctionA = (PFuncA)GetProcAddress(hDllHandle, TEXT("FunctionA"));
     DWORD errSetParam = GetLastError(); 
	
     PFuncB pFunctionB = (PFuncB)GetProcAddress(hDllHandle, TEXT("FunctionB"));
     DWORD errExecute = GetLastError();

     ASSERT(pFunctionA != NULL);
     ASSERT(pFunctionB != NULL);
 //some initialization
 
    pFunctionA((char* const)ParamName.GetString(), (char* const)ParamValue.GetString());
 
    nFileUpdated = pFunctionB((char* const) param1.GetString(),(char* const)param2.GetString(), (char* const)param3.GetString(),(char* const)param4.GetString(),(char* const)param5.GetString(),
(char* const)param6.GetString(),(char* const)param7.GetString(),(char* const)param8.GetString(),param9);
 
// and the definition which are before this code are :
 
typedef int (CALLBACK* PFuncA)(LPCSTR, LPCSTR);

 typedef int (CALLBACK* PFuncB) (LPCSTR, LPCSTR, LPCSTR, \
                             LPCSTR, LPCSTR, \
                             LPCSTR, LPCSTR, LPCSTR, bool); 
 }
Posted
Updated 2-Aug-12 3:09am
v3
Comments
enhzflep 2-Aug-12 5:36am
   
Looks like name mangling to me. That is to say - it sounds like the offending dll may not have the extern "C" prefacing it. When compiled with a c++ compiler, the function names are altered internally by either the compiler/linker - I forget.

Can you check the source of the dlls to ensure that the way the functions are declared is consistent?
Argonia 2-Aug-12 5:45am
   
yes i am sure i just checked it
Malli_S 2-Aug-12 6:35am
   
Check for any overloaded function of the same name. Or there could be error/mismatch in the def file.
Argonia 2-Aug-12 6:46am
   
Checked nothing . I tried to enumerate the functions in .def file with @1-N where N is the number of the exported functions . Still GetProcAddress() returns invalid not null address with no function in it
GetLastError() returns 0
pasztorpisti 2-Aug-12 8:36am
   
If the function declaration and calling convenction is the same in your dll and in your pointer declaration, then all you have to do is fixing the name of the function either on the DLL side or on the user side wher you call GetProcAddress().
_<funcname>@number is the name mangling used for stdcall functions - the number is the size of the parameters that is cleant up from the stack by the function, since its stdcall.
I think using such a name with GetProcAddress() is self suicide (because of maintenance) especially if oyu have lot of function calls so use extern "C" when you are loading the DLL by yourself. With static linking its ok to use stdcall name mangling.

Anyway, what language do you use and how many exported functions do you have?
Richard MacCutchan 2-Aug-12 8:47am
   
Please edit your question and show the actual code you use, from LoadLibrary() through to the call to the exported function. I have used this functionality many times without difficulty.
pasztorpisti 2-Aug-12 8:52am
   
What is the string that you pass to GetProcAddress() as a function name?
pasztorpisti 2-Aug-12 9:32am
   
You don't have to use the TEXT macro with GetProcAddress() since it doesn't have widechar version, but this isn't the source of problems, your program just wouldnt compile wiht unicode character setting in your project file. Anyway, this still isn't enough info to find out the source of problem I think. This is an easy problem and you make a mistake, but who knows where... I see ppl facing with DLL problems often, I will write an article about practical DLL useage soon. Unfortunately many ppl don't know when to use DLLs and how.
Argonia 2-Aug-12 9:36am
   
When i check what is in the function pointers there is only some place in the memory. If i check the other "working" pointers they have the mangling name which i saw in the dumpbin / exports
pasztorpisti 2-Aug-12 9:38am
   
Not NULL pointers? Thats interesting... But the reason for this can be that your debugger doesn't know about that dll debuginfo in one of the cases. If the function pointer is not null then GetProcAddrsss() succeeded so the problem is somwhere else.
Argonia 2-Aug-12 9:41am
   
not null and that GetLastError() doesn't return anything
I guess my question got too long for someone to read :)
Please see what i wrote about the dll and dumpbin /exports i think something isn't right with it
pasztorpisti 2-Aug-12 9:43am
   
The problem isn't with the dumpbin stuff and function name if GetProcAddress() returns other than NULL.
pasztorpisti 2-Aug-12 9:46am
   
Your question is still too short for someone to find out the problem. :-) Noone can tell you what the problem is from what you published till now.
pasztorpisti 2-Aug-12 9:54am
   
Are you shure that the right dll is loaded? It can be loaded from many directories (search path) if you copied a lot of DLLs here and there then you can check the DLL path by calling GetModuleFileName() on the DLL handle or you can specify full path name temporarily for LoadLibrary().
Argonia 2-Aug-12 10:00am
   
I call LoadLibrary() with full path
pasztorpisti 2-Aug-12 10:03am
   
I guess in your crashy situation dumpbin returns the same name you pass to GetProcAddress() because it doesn't return NULL. In this case your connection to the DLL is successful so your code crashes when you call the DLL (someone already mentioned that), so something is wrong with the cooperation between your code and the DLL. You should debug it, we don't even know whats the actual error in your case. Crash? something else???
Argonia 2-Aug-12 10:08am
   
it doesn't crash .It doesnt call the functions it should and when i use the second pointer the program jumps to some irrelevant function not even from the same dll even i am not sure whats going there cuz when i debug it i saw that it takes the next message from the message queue and just executes the handler.For the first pointer when i use it as far as i understand from the disassembly it just moves some info in the memory it tries to call something but nothing happened
Argonia 2-Aug-12 10:03am
   
I don't understand how the older version of the same dll shows that mangling names when i use dumpbin and the new version is just the names from .def file .That strange to me
pasztorpisti 2-Aug-12 10:07am
   
Maybe you changed compilers/linkers, do you have newer version. I'm aware of name manglins for a very long time, but I remember that I also had a strange situation with C and stdcall mangling where I couldnt found out exactly what switches between the 2. Since you are using extern "C", the name should appear without @number and '_' prefix in all cases.
Argonia 2-Aug-12 10:09am
   
No both versions are compiled /build in Visual Studio 2010. In the second dll (the new ) they dont appear that way . The old is ok and there everything work normally i tested it

pasztorpisti 2-Aug-12 10:14am
   
What has changed then???
Argonia 2-Aug-12 10:18am
   
few bugs were fixed , some function were changed nothing major
pasztorpisti 2-Aug-12 10:22am
   
I hope you are using some kind of version control system. Save your changes and either revert them one by one, or revert everything and add the bugfixes again one by one until you find out what causes the crash.
Argonia 2-Aug-12 10:25am
   
one word - wincvs :D its good i didn't update all my versions of the project.
pasztorpisti 2-Aug-12 10:30am
   
So now its working?
pasztorpisti 2-Aug-12 10:39am
   
Update from cvs to at least svn as soon as possible... ;-)
pasztorpisti 2-Aug-12 10:18am
   
BTW, I didn't remember what the magic is, but I tried it in my VS2008 and it works like this:
If the implementation of your dll function is in a .cpp file then it works as follows: If you export stdcall function without .def file with __declspec(dllexport) then it will have an extremely weird C++ name mangling (that is usually different in debug/release configs under VC++ if I remember right). If you export with .def file or .def file + __declspec(dllexport) then the name wont be mangled at all.
If the implementation of your dll function is in a .c file then without a .def file with __declspec(dllexport) you get an stdcall mangling like _<funcname>@<paramsize> and with a .def file you get unmangled name.
So: .def file unmangles the name in all cases. You get stdacall mangling with __declspec(dllexport) if the dllfunc is in a .c file.
Argonia 2-Aug-12 10:19am
   
its written in c++ with .cpp files and nowhere in the dll i have __declspec(dllexport) only extern "C" __stdcall and .def file
Rate this:
Please Sign up or sign in to vote.

Solution 1

You probably have to declare type like this
extern "C" {
typedef <type> (CALLBACK * <name> )(<type of="" params="">)
}
   
v3
Comments
Argonia 2-Aug-12 6:21am
   
still the same . The functions doesn't get called
armagedescu 2-Aug-12 8:22am
   
If function does not get called, then there is other problem. If the signature is wrong, then function usually get called, but it crashes at runtime. But if it does not get called, then problem is elsewhere. The dll have to declare function with __declspec(dllexport) but application which loads the dll have to declare it as __declspec(dllimport).
Anyway, try to debug and see if dll is still loaded when you want to call the function, and what exactly is called when you call the function. Try to debug in disassembly, and see what happens after ASM call is instruction is executed. You also can open memory window and enter the address of function.
In many times GetProcAddress can get the address of a jmp instruction. In that case you have to see where this it jumps, what is on the memory.
Rate this:
Please Sign up or sign in to vote.

Solution 2

Refresh your workspace using you CVS client. ;-)
   
Comments
Argonia 3-Aug-12 2:13am
   
I am an absolute idiot . The problem was in the post build events . We are using env folder and in these events the built dlls were copied into the folder with the old names.Thanks to all who answered my question espetially pasztorpisti :)
Malli_S 3-Aug-12 3:08am
   
lol !
But it was nice discussion.
pasztorpisti 3-Aug-12 7:22am
   
:-) this happens sometimes, especially with multiple workspaces and complex build systems.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100