Solved

Accessing function in a DLL via LoadLibrary and GetProcAddress

Posted on 1998-10-09
10
498 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
  • 6
  • 3
10 Comments
 
LVL 22

Accepted Solution

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

Expert Comment

by:jhance
Comment Utility
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
Comment Utility
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
 
LVL 22

Expert Comment

by:nietod
Comment Utility
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
Comment Utility
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
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 

Author Comment

by:Nitemare
Comment Utility
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
Comment Utility
>> 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
Comment Utility
Try

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

Expert Comment

by:nietod
Comment Utility
>> 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
Comment Utility
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

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

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 …
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

744 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now