Solved

Dynamic load of classes

Posted on 2000-03-06
9
193 Views
Last Modified: 2010-04-02
I can write and compile a Win32 DLL in C++ and then dynamically load the library and use its exported functions by using LoadLibrary() and GetProcAddress() API calls. But can I similarly load and use classes and methods?
0
Comment
Question by:CesarGon
  • 4
  • 3
  • 2
9 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 100 total points
ID: 2588729
See http://www.codeguru.com/win32/dyndllclass.shtml - this artivle (and the followups) discuss this issue...
0
 
LVL 22

Expert Comment

by:nietod
ID: 2588740
Opps.  jkr beat me.  here's what I had.

Yes and no.

There are some problems.  How do you create an object, if yoiu don't have the class's definition and constructor?   Once you have the obkject, how can you call its member functions.  Not all member procedure calls can be invoked using a pointer returned from GetProcAddress.   This stuff is circumventable, but it gets really messy.  fortunately there is a good solution

continues
0
 
LVL 22

Expert Comment

by:nietod
ID: 2588747
And here is an example I was going to post.  It'll give you a 2nd point of view.

************ Base.h*******
// Note no export directive.  Not of any value for you
// since you are linking at run-time.
class Paths {
 public :
         Paths() ;
        // note all functions are virtual, because linking
        // is to be done through the VTBL  No need for
        // GetProcAddress().
         virtual ~Paths() = 0;;
         virtual int DoSometingWith (int x, int y)  = 0;
         vitual char* SomethingElse (int v, char *w) = 0 ;
};

// Type defintition for the "factory" function.
typedef Path * (*MakePtrTyp)();

***********Dll.cpp************
#inlude "Base.h"

// Derived concrete class.  Functions can be added here that
// are not virtual, so long as they are not to be used by the EXE.
// Any functions the EXE uses must be virtual.
class DerivedPaths : public Paths
{
public:
         DerivedPaths() ;
         virtual ~Paths()  {};
         virtual int DoSometingWith (int x, int y)  { return x+y; };
         vitual char* SomethingElse (int v, char *w)  { return w+v; } ;
}

// The factory function.  Uses extern "C" so that it is easier for
// the EXE to get using GetProcAddress();
extern "C" Paths *MakePaths()
{
    return new DerivedPaths;
};

***************EXE.cpp*****************
WinMain()
{
   HINSTANCE PathLib = Loadlibrary("some path");
   MakePtrTyp MakeProc = (MakePtrTyp) GetProcAddress(PathLib,"MakePaths");

   Paths *PathsPtr = (*makeProc)(); // Make a paths object.

   PathsPtr->DoSomethingWith(1,2);
   delete PathsPtr;
}

A couple more words of explanation.  

The only time you need to use GetProcAddress() with this scheme is to find the factory function in the DLL that creates the objects.  All the other functions are handled through virtual functions calls.  That is obviously much more convenient than lots of GetProcAddress() calls!

The DLL allocates objects using new and the EXE eventually deletes it with delete.  For this to work the two must share a common heap, this means you must use the DLL version of the run-time library.  (a good idea in any case.)  Another alternative is for the DLL to have a function that does the delete, but I would do the other.

The EXE can load different DLLs that define different derived classes.  So if the derived class has different versions or changes with time, the EXE does not need to be recompiled.

This approach is in many ways the C++ version of COM.
0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 3

Author Comment

by:CesarGon
ID: 2588781
Thanks to nietod as well!
0
 
LVL 86

Expert Comment

by:jkr
ID: 2588920
Sorry Todd, typing an URL you know by heart simply is faster ;-)
0
 
LVL 22

Expert Comment

by:nietod
ID: 2589584
Yeah, you get the points and I get the "honerable mention".  I'm going to loose my ranking any minute now...
0
 
LVL 86

Expert Comment

by:jkr
ID: 2589833
Well, I fear so, too ;-)
0
 
LVL 3

Author Comment

by:CesarGon
ID: 2590883
In fact, answers from you both jkr and nietod have been very valuable. May you share your points? 8-)
0
 
LVL 22

Expert Comment

by:nietod
ID: 2591461
Its not really possible or even really necessary.   (I beat hin to the answer more than he beats me, so I don't want to start a sharing policy.  :-)  )
0

Featured Post

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

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

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

828 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