Solved

Accessing function in a DLL via LoadLibrary and GetProcAddress

Posted on 1998-10-09
10
538 Views
Last Modified: 2012-05-04
So far I used to load dlls at load-time therefore compiled my programs with .lib file that linker made when building a dll. Now I've come to a situation when I would like to execute a function in a dll via LoadLibrary. Well it works to the point when I issue a command GetProcAddess which never gets a lock onto function that I know is in a dll (I made my dll).
When I tried to see what's in the Export table of a dll through quick view in Win95 I saw nothing. The export table showed up only if I quick view a dll in WinNT. Why????
The other thing is that the name of a function looks like this : 0000 ?Func1@@YAXXZ or something. Strange that ordinal number began with 0 instead of 1. My function is simply void Func1 (void) and nothing else. I exported it via __declspec(dllexport). Otherwise if I include .lib file that was generated with dll to my .exe I can successfuly call Func1.

What am I doing wrong????
0
Comment
Question by:Nitemare
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
10 Comments
 
LVL 22

Accepted Solution

by:
nietod earned 100 total points
ID: 1174756
Declare the functions as extern "C"
0
 
LVL 32

Expert Comment

by:jhance
ID: 1174757
I assume that you are using C++.  If so, then the problem is what is called name "mangling" or decoration by the compiler.  In order to make sure that there are no name collisions between the different functions in a class, the compiler does some things to the names of each function to ensure that it is unique in all cases.  This is normally transparent to the user of a program or static library as you don't ever deal with the names of the functions except at compile time, and they are not decorated at that point.  Using a DLL, however, required that you know the name of the function as it appears in the DLL itself.  There are three ways around this problem:

1) Use ORDINALS to select the function instead of the name.
2) Look in the symbol table and get the decorated name of the function (a real pain as the name can change)
3) Use extern "C" before your function declarations.  This forces the compiler to use "C" name conventions for this function instead of decorated C++ names.

I tend to use #3 for exported functions.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1174758
The problem is C++'s name decoration.  This is a system by which C++ adds suff to the end of the name (the stuff you saw) in order to "descrbe" the parameters to the function.  By doing this, overloaded function which _appear_ to have the same name in C++ are actually generated with unique names.  You can use GetProcAddress() witht he appropriate decorated name (just tack on all that stuff you saw), but that is not recmended.  The name decoration system is not standardized, so differnet compilers or even different versions of the same compiler will generate different decorations.  Thus this might require you to change the name from time-to-time.  So instead, if you dissable the decoration process, you can load the procedure with the name you gave it.  If you declare the procedure as extern "C", it will not be decorated.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 22

Expert Comment

by:nietod
ID: 1174759
One more thing, if you use extern "C", you have dissabled the overloading scheme on that particular function.  You can still overload other functions and you can even overload other functions with the same name.  However, you cannot overload two functions that have the same name and are both declated extern "C".
0
 

Author Comment

by:Nitemare
ID: 1174760
OK let's assume this example:

This goes for a dll file

#include <stdio.h>

void __declspec(dllexport) Func1(void)

void Func1(void)
{
   printf ("Func1 output\n");
}

Now when I call a function in my exe I do next

typedef void (*MY)(void)

    MY myroc;

LoadLibrary and so on....

    myproc = (MY) GetProcAddress(hinst, "Func1");
And this is where all stop

I could call a function then like : (myproc)();

declaring a Func1 as extern is not important since a function gets called via pointer. Furthermore this is like an example from a book and it doesn't work!!!

The only thing I didn't check at the moment of writing this comment is if I should change the exact function name specified in GetProcAddress and how to disable name mangling or whatever that is so that dll would reflect the function names like if you look say User32.dll and all you see are "clean" function names.

Any suggestions...
Something tells me I should stick to straight C not C++ when writing dlls.
0
 

Author Comment

by:Nitemare
ID: 1174761
Calling a function with ordinals is out of question since my program should run on NT as well as on 95/98 and ordinal assignment is different on those two.... am I wrong here too
0
 
LVL 22

Expert Comment

by:nietod
ID: 1174762
>> Something tells me I should stick to straight C not C++ when writing dlls
not true at all.  But if you want to load a procedure by name (GetProcAddress()) then you will want to dissable name mangeling.

As I said before.  You either need to specify the mangled name to GetProcAddress().  That is, the name you found when you looked at the DLL's exports. OR (better yet) dissable name mangeling by declaring the function as extern "C"

0
 
LVL 22

Expert Comment

by:nietod
ID: 1174763
Try

extern "C" void __declspec(dllexport) Func1(void)
{
     printf ("Func1 output\n");
}
0
 
LVL 22

Expert Comment

by:nietod
ID: 1174764
>> Calling a function with ordinals is out of question since my program
>> should run on NT as well as on 95/98 and ordinal assignment is different
>> on those two.... am I wrong here too
The ordinals of someof the OS DLLs may be different.   (I never heard that before , however).  But that doesn't have any effect on a DLL you write.  When you create the DLL, you specify (or at least determine) the ordinals.  That won't change unless the DLL is altered.  It can be copied to a computer using either OS and the ordinals will stay the same.  (Basically the DLL has a list of exported functions that is numbered starting fom 0.  The ordinal of a function is its position in the list.)  

So you can load by ordinal, but I wouldn't recomend it unless you are very sure that the DLL won't need future modifications.  Modifications that add or remove exported procedures makes loading by ordinal a little more risky, or at least a little more difficult.  (It is however faster and generates smaller code.)
0
 

Author Comment

by:Nitemare
ID: 1174765
nietod yes I tried that and it works as it works calling a func with mangled name. The portion about different ordinals is explained in Programming Windows NT 4 from SAMS Publishing. I figured that tricky extern declaration now when it was brought to me. Good work. Thx.
Jhance thx to you too but I can only give points to one. Next time.
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

630 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question