Click here to Skip to main content
Click here to Skip to main content

A class to wrap DLL functions

By , 25 Jun 2002
 
<!-- Download Links --> <!-- Add the rest of your HTML here -->

Introduction

My project needs to manage a large set of DLLs. All of them export a same set of functions. None of them link with the main project at compile time. We call them PlugIns. These plugins are used to extend the ability of the main program. Once they are copied into the program directory, the program can use them, and if they are removed from the directory, the main program works just fine, except that some functions cannot be used.

Since these DLLs are not available at the time that the main program is compiled, we have to use LoadLibrary, GetProcAddress and FreeLibrary to use these DLLs. It's really boring! I needed a class to ease this job. In fact, these DLLs looks just like classes (they all have the same interface: a set of functions). Using a class to wrap these DLLs is just reasonable.

Here comes the class CDLLModule. This class is only for deriving. Let's see how to use it first. Suppose you have a DLL which export two functions like this:

 
    int WINAPI GetEngine(char *szEngineType, char *szEngineVersion);
    int WINAPI StartEngine(HWND hWnd);

The wrapper class would like this:

class CMyClass : public CDLLModule
{
    DECLARE_DLL_FUNCTION(int, WINAPI,
                          GetEngine, (char *, char *))
    DECLARE_DLL_FUNCTION(int, WINAPI,
                                  StartEngine, (HWND))

    BEGIN_DLL_INIT()
        INIT_DLL_FUNCTION(int, WINAPI,
             GetEngine, (char *, char *), "GetEngine")
        INIT_DLL_FUNCTION(int, WINAPI,
                   StartEngine, (HWND), "StartEngine")
    END_DLL_INIT()
};

Then we can use it like this:

    CMyClass    module;
    module.Init("MyDLL.dll");
    module.GetEngine(m_str1, m_str2);
    module.StartEngine(m_hWnd);

I should explain it in more detail, but I am really not good at English. Anyway, the code is very simple, only 64 lines including comments. I think it's very useful, and I hope you think so too.

One last thing. It's a good idea to check the validation of the function before calling. In another word, if you are not sure that all functions are exported well from the DLL, Call it like this:

    if (module.GetEngine)
        module.GetEngine(m_str1, m_str2);

Enjoy :)

Revision History

26 Jun 2002 - Initial Revision

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Neil Yao

China China
I'm a chinese programer living in Shanghai, currently working for a software company whose main business is to deliver computer based testing. Software simulation for computer based testing and certifications is my main responsibility in this company. Execpt for software development, I like out-door activities and photography. I am willing to make friends in China and all over the world, so contact me if you have anything in common with meSmile | :)

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionFreeLibrary function VS 2005 - WXP Pinmemberpicm24-Apr-10 1:30 
hi Neil,
 
we have an .exe that manages several dll. Ours architecture loads dynamically several dlls and also it is possible to exchange instance of class between dlls. We have a problem after Freelibrary() function. It seems that a FreeLibrary() function deletes a memory used by another dll. After FreeLibrary I find corrupted a __vfptr table in a class allocated in the another dll. If I change the order of dlls loading and unloading the problem disappears (But It can't be a solution Sniff | :^) ).
 
Could you help me??
 
Thanks
M.
picm

GeneralHummmmmm PinmemberKelly Cristina Mara2-Mar-08 12:10 
Could you teach more about DLL?
 
I will be wait for:
 
Kellyc.mara2007@hotmail.com
GeneralMeaning of the second parametr DECLARE_DLL_FUNCTION Pinmemberbadzio23-Feb-07 2:40 
Hi
DECLARE_DLL_FUNCTION is declared as
DECLARE_DLL_FUNCTION(ret, cc, func, params)
What means 'cc'?
In your example this is WINAPI but i don't know what WINAPI is?
 
------------------------------------------
gourangaWink | ;-)
JID badzio(at)chrome(dot)pl
------------------------------------------

GeneralRe: Meaning of the second parametr DECLARE_DLL_FUNCTION Pinmemberbadzio23-Feb-07 2:57 
GeneralDLL code Pocket PC PinmemberZiggy2k27-Sep-05 6:26 
I have a dll that is in itself a program for the pocket pc (windows mobile 2003 SE)
 
but i want to edit the code
but i cant seem to open it
so do you have any idea how i can conver the file to make i usable?
if you want i can send you the file
 
thnx in advance for any replies
 
Ziggy
GeneralRe: DLL code Pocket PC PinmemberNeil Yao27-Sep-05 18:56 
GeneralOPSEC SDK PinsussAnonymous24-May-05 5:34 
Hi Guys , i want one help Regarding OPSEC SDK.
Open Platform for Security SDK is provided by Check point server which contains API's written in C also it contains many header files dlls etc..
 
I am new to C language and donot know how can i use the functions etc.. in C# with the matching datatypes....
 
Can anybody help me for writting the warpper class for it
 
Thanks and Regards,
Nitin.


QuestionWhat abt Consructor and others?? PinmemberPradip K. Jadav4-Mar-05 19:42 
hello ,Its nice wrapper. Smile | :)
I have solved my some errors which were about functions. So i used ur wrappers for these functions.
Actually I am going to create a Shared Dll. So some linking errors were coming. Errors for functions solved but what about Constructor and Destructor?? and likewise that others??
here is my code ....
 
class Section {
friend class Subsection;
protected:
bool enabled;
string name;
string comment;
string desc;
FieldVector field_vec;
virtual void update() = 0;
SubsectionVector sub_vec;
public:
static SectionMap map;
Section(string, int);
virtual ~Section();

 
Now my question is what about class named SectionConfused | :confused: , constructor named Section(string, int)Confused | :confused: and destructor named virtual ~Section()Confused | :confused:
Plz provide some extra wrappers for that also ..Help will be appreciated..
waiting for reply..

 
With Best Regards,
Pradip K. Jadav

QuestionHow to calling this DLL into VB6 Pinmemberalejorb7-Aug-04 6:48 
Hello
 
Great article, congratulation!!
 
But, how to calling this dll Class from VB.
 
Bye.
AnswerRe: How to calling this DLL into VB6 PinmemberYao Zhifeng8-Aug-04 15:45 
This is a class to ease the work of calling DLL functions in C++. This is not a DLL. And nothing related with VB.
Generaltanx Pinmemberasd175325-Nov-03 10:41 
it's a very useful thing .
GeneralRe: tanx PinmemberRalph Wetzel9-Apr-04 2:29 
Generalcannot access private member declared in class 'CDLLClass' Pinmemberposbis9-Sep-03 10:43 
Hello all
 
I tried to wrap some DLL functions of a DLL of mine with DLLModule.h It looked simple and efficient to me but I can't get it working. My VC++ 6 always bails out with the following error message during compile.
 
error C2248: 'Init' : cannot access private member declared in class 'CDLLClass'
            i:\advancedpipeserver\aps\aps.h(149) : see declaration of 'Init'
 
The definition of my class looks as follows:
 
class CDLLClass : public CDLLModule
{
      DECLARE_DLL_FUNCTION(long, WINAPI, KillProcessByName , (char *) )
      DECLARE_DLL_FUNCTION(long, WINAPI, ExistProcessByName, (char *) )
 
      BEGIN_DLL_INIT()
            INIT_DLL_FUNCTION(long, WINAPI, KillProcessByName , (char *), "fnKillProcessByName")
            INIT_DLL_FUNCTION(long, WINAPI, ExistProcessByName, (char *), "fnExistProcessByName")
      END_DLL_INIT()
};
 

The initialisation of the class is done like this:
 
CDLLClass      *aps_module;
 
aps_module = new CDLLClass;
aps_module->Init("apsdll.dll");
 
If I comment the "Init" function I can compile and can see the functions wrapped inside the class.
 
-aps_module     0x008249f0
-CDLLModule     {...}
-__vfptr     0x00429184 const   CDLLClass::`vftable'
     [0]     0x004011a4 CDLLClass::`vector deleting destructor'(unsigned int)
     [1]     0x00401023 CDLLClass::Init(char const *)
-m_hDLL     0x00000000
     unused     CXX0030: Error: expression cannot be evaluated
     KillProcessByName     0xcdcdcdcd
     ExistProcessByName     0xcdcdcdcd
 

So I can see my functions declared but what looks strange to me is that the function "IsLoaded()" is missing. "Init" and "Destructor" are defined in the "virtual function pointer table" of the class. But to my knowledge, this is only the virtual Init-function from the base class CDLLModule. So far so good but why do I see this strange error message as soon as I uncomment my
"aps_module->Init...." line ? It doesn't see or should I say accept the Init-Function produced from the MACROS.
 

Any idea ?
 
Regards
Oliver
GeneralRe: cannot access private member declared in class 'CDLLClass' Pinmemberposbis9-Sep-03 10:58 
GeneralRe: cannot access private member declared in class 'CDLLClass' PinmemberYao Zhifeng9-Sep-03 14:59 
Questionhow to use it with no arguements Pinmembernikhilpp8-Aug-03 7:43 
Hi,
I am trying to use this technique. Can anybody show me how to use this for a function that takes no arguements.
 
Thanks...
 
-Nikhil
AnswerRe: how to use it with no arguements PinmemberYao Zhifeng11-Aug-03 15:05 
GeneralSuggestion to use typedef in the macros PinmemberAndrew Schetinin5-Jul-03 22:45 
Hi,
 
I once invented a similar class by myself but your is much more cleaner and effective Smile | :) I like it a lot.
 
One thing that bothered me is the dual function definition so I used typedef:
#define DECLARE_DLL_FUNCTION( return_type, spec, function_name, params ) \
    typedef return_type (spec PROC_##function_name) params; \
    PROC_##function_name * ##function_name;
and
#define INIT_DLL_FUNCTION( function_name ) \
    if( NULL != m_hDLL ) \
        function_name = (PROC_##function_name *) GetProcAddress( m_hDLL, #function_name ); \
    else \
        function_name = NULL; \
    if( NULL == function_name ) \
        bOk = false;
 
Now you can first use DECLARE_DLL_FUNCTION macro as usual, and than have the clean INIT_DLL
 
BEGIN_DLL_INIT()
    INIT_DLL_FUNCTION( ComposeMail )
    INIT_DLL_FUNCTION( OpenMail )
    INIT_DLL_FUNCTION( CloseMail )
    INIT_DLL_FUNCTION( ExtractMailAttachment )
END_DLL_INIT()
 
I hope you'll like it Smile | :)

 
--
Best Regards,
Andrew
GeneralI forgot about UNICODE too PinmemberAndrew Schetinin5-Jul-03 22:51 
Generalcreating a Game engine DLL Pinmembersriniatig10-Apr-03 22:57 
I have written a small game engine for strategy games. I just realised that I now want to convert my engine into a DLL which can be loaded in by other programmers in my group which will help them to access my functions dynamically.
My game engine is written in VC++ using DirectX..
Plz advice.
 
Srinivasan Veeraraghavan
Game Programmer
srinivasan@indiagames.com
GeneralRe: creating a Game engine DLL PinmemberYao Zhifeng13-Apr-03 15:38 
GeneralRe: creating a Game engine DLL PinmemberAndrew Schetinin3-Jul-03 3:36 
GeneralHeader From lib Pinmemberbfadi2-Mar-03 14:15 
Hi,
Any one know how to get the .h file from .lib file ?
Thanks
GeneralDebug Error! PinsussJack Furr14-Feb-03 22:19 
This is a great way of handling the plug-in code.
 
I do have one problem.   I get the following error:
<snip...>
"the value of ESP was not properly saved across a function call."
<snip...>
 
I understand the error (and no, removing the /GZ will only HIDE the error), but I can't seem to figure out what's different in the call.

Here's my (simplified) DLL func:
extern   "C" _declspec(dllexport) int StartEngine(HWND hWnd)
{
return 1;
}

GeneralRe: Debug Error! PinsussJack Furr15-Feb-03 15:14 
Generalanother question Pinmemberalexkid99918-Dec-02 23:17 
Smile | :) Does this class work fine with Pocket pc and Evc++??????Confused | :confused: Confused | :confused:
GeneralRe: another question PinmemberYao Zhifeng19-Dec-02 14:02 
QuestionSomeone could help me????? Pinmemberalexkid9995-Dec-02 23:51 
I have implement a standard MFC dll and I have export a function pInit(void)
but when I would like use this dll.
My derived class CPlugin don't work load the dll
could someone help me please!

AnswerRe: Someone could help me????? PinmemberYao Zhifeng8-Dec-02 18:57 
GeneralRe: Someone could help me????? Pinmemberalexkid9998-Dec-02 22:16 
Generalunsigned int* return value of dll function PinmemberJuergen Klingler23-Aug-02 1:33 
Hello YAO,
how should I declare the things, if the return value
of the dll function is an unsigned int*?
 
Thanks for you help
juergen
GeneralRe: unsigned int* return value of dll function PinmemberYao Zhifeng25-Aug-02 21:50 
QuestionHow to dynamically load a MFC dll ? PinmemberWilliamXu5188-Jul-02 4:56 
Hi, everyone,
 
How to load a MFC dll, which itself uses _declspec( dllexport ) type function export from another dll, with using LoadLibrary()? When I use LoadLibrary() to load the dll it always return to me a NULL.
If I comment out the function call to the _declspec( dllexport ) type of function, then LOadLibrary will successfully load the dll. How can I solve this problem? If I use WINAPI to replace the _declspec(dllexport), the compiler will complain me extern function is not resolved.
Thanks in advance.
GeneralThere is one more approach -- DELAYLOAD Pinmemberigor196026-Jun-02 17:39 
You can investigate possibilty of DELAYLOAD linker switch...
When you have bunch of possible .DLLs, but only one should be loaded during runtime => here is an alternative and very elegant solution:
Suppose you have A.DLL, B.DLL, C.DLL and during runtime you will load only one of it, based on some interpretation...
So, during build create X.DLL that has all common methods of A,B and C that you want to EXPORT...
Now, use X.LIB to link with your executable...
In you exicutable before calling any of X Exported functions, and after what DLL (A,B or C) should be loaded copy one of A, B or C into X.DLL...
Sure, you have to link with DELAYLOAD:X.DLL...
 

GeneralRe: There is one more approach -- DELAYLOAD PinmemberArbesto Pelta27-Jun-02 3:24 
GeneralRe: There is one more approach -- DELAYLOAD Pinmemberigor196027-Jun-02 17:57 
GeneralRe: There is one more approach -- DELAYLOAD PinsussAnonymous5-Nov-02 10:26 
GeneralRe: There is one more approach -- DELAYLOAD PinmemberPhilippe Lhoste1-Jul-02 2:56 
GeneralRe: There is one more approach -- DELAYLOAD PinmemberArbesto Pelta1-Jul-02 8:04 
GeneralRe: There is one more approach -- DELAYLOAD Pinmemberigor19601-Jul-02 21:15 
GeneralRe: There is one more approach -- DELAYLOAD PinmemberPhilippe Lhoste1-Jul-02 21:47 
GeneralRe: There is one more approach -- DELAYLOAD PinmemberAnonymous2-Jul-02 19:27 
GeneralRe: There is one more approach -- DELAYLOAD PinmemberPhilippe Lhoste2-Jul-02 22:04 
GeneralRe: There is one more approach -- DELAYLOAD PinmemberAnonymous5-Jul-02 21:13 
GeneralRe: There is one more approach -- DELAYLOAD PinmemberPhilippe Lhoste7-Jul-02 21:54 
GeneralRe: There is one more approach -- DELAYLOAD PinmemberArbesto Pelta10-Jul-02 10:20 
GeneralRe: There is one more approach -- DELAYLOAD PinmemberPhilippe Lhoste10-Jul-02 21:53 
GeneralAnybody know how to modify the article after being removed from the unedited section PinmemberYao Zhifeng26-Jun-02 15:42 
thx
GeneralRe: Anybody know how to modify the article after being removed from the unedited section PinmemberKarstenK20-Feb-03 23:09 
GeneralAnalogy with HTTP homemade APIs vs. SOAP PinmemberJoaquín M López Muñoz26-Jun-02 13:47 
The thread below about the suitability of using COM instead of this simple approach reminds me of the hype that SOAP is being given these days. Many folks suggest everyone to switch to SOAP in every occasion instead of resorting to good old GETs and POSTs with some custom return format, without a second thought on the burden imposed by this huge technology, both in terms of efficiency and complexity of development. In many situations, what could have been dealt with in a couple of hours worth of coding becomes a major nightmare, just for the sake of the promised flexibilty SOAP is supposed to bring along. Sure SOAP can be great for middle to large projects, but most of the time it adds next to nothing to a simpler approach.
 
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130617.1 | Last Updated 26 Jun 2002
Article Copyright 2002 by Neil Yao
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid