Wrapper Classes for Dynamic DLL Loading

Environment: Win32, C++, MSVC 6.0

I needed to develop a program which requires a DLL that is usually found in the Windows system directory. Sometimes this DLL is not installed at all. To make things worse, the utility that needs the call the DLL is not allowed to leave any footprint when removed, so installing in the system directory or changing the registry is not an option. However, it is required to use the DLL from the system directory whenever it is available.

The installation utility doesn't allow the customization of the installed files based on the OS. In some cases, however, a different implementation is needed for different operating systems. A possible solution is to put different DLLs in different subdirectories, then first try to access the system directory. If the DLL is not there, then go to the subdirectory specific for the operating system.

Additionally, I don't believe people love to write all these LoadLibrary and GetProcAddress statements, even if the delayed DLL loading linker option can help here in the simpler cases.

To handle the requirements, I wrote a set of classes and templates that wrap LoadLibrary and GetProcAddress and allow to specify multiple directories to search for the DLL and the order to look in them. The most interesting part of the solution are the templates, which may look like this:

template
<
   typename T_RET, 
   typename T_P1, 
   typename T_P2, 
   const TCHAR * const * _pszDllName = NULL, 
   const char  * const * _pszExportName = NULL
> 
class LoadProc2Wrapper : public LoadProcWrapperBase
{
protected:
   typedef  T_RET (WINAPI * t_pf) (T_P1, T_P2);
 
public:
   LoadProc2Wrapper() : LoadProcWrapperBase()
   { 
      if (_pszDllName != NULL && _pszExportName != NULL)
      {
         SetNames(*_pszDllName, *_pszExportName);
      }
   }
 
   virtual T_RET operator() (T_P1 p1, T_P2 p2)
   {
      GetTheFunction();
      return ((t_pf)m_pf)(p1, p2);
   }
};

The constructor initializes the base class with the DLL name and function name from the template instance. The function operator first calls the base class to locate and load dynamically the DLL and put the function address into m_pf, then casts this pointer to the actual type and returns with the return type and value of the function. The class LoadProcWrapperBase handles all path and module manipulations.

The above sample is simplified to illustrate the main idea. If you look at the attached sources, there are two intermediate layers of templates there one that provides the constructor, and another that manages default return values that can be used if the function is not located in the DLL.

Two sets of macros expand that the templates are included for zero to four parameters. One set is used for functions that return values, the other is for functions returning void or when return value is not necessary. I am not sure if casting void return type on functions that return a value is 100% safe, so I would recommend to use the macros with no return value really only for exported functions returning void. The macros must be expanded at global level, because templates can only take constant pointers to objects that have external linkage type.

Sample use

// macros must be expanded at global level

// potentially unsafe, Sleep returns a value
LOADPROC_NO_RETURN_VALUE_1(kernel32_Sleep, "kernel32",
                           "Sleep" , int); 

// potentially unsafe, Beep returns a value
LOADPROC_NO_RETURN_VALUE_2(MyBeep, "kernel32", "Beep",
                           int, int);

// 4th parameter in LOADPROC_WITH_RETURN_VALUE_X 
// macros is the return type
LOADPROC_WITH_RETURN_VALUE_2(MyBeep2, "kernel32",
                             "Beep", int, int, int);
LOADPROC_WITH_RETURN_VALUE_1(TESTMISSING, "kernel32",
                             "ThisOneDoesntExistFroSure",
                             int, int);

void test(void)
{
   kernel32_Sleep slp;
   MyBeep         f2;
   MyBeep2        f3;
   TESTMISSING    foo;

   // Loading order, up to three directories + default
   // LoadLibrary behavior
   // CLsd provides an easy way to define the Windows
   // directory, system directory,
   // current directory and executable directory
   slp.SetPreferredPath("d:\\",
                        CLsd(CLsd::E_SYSTEMDIR),
                        ".");

   f2(880,200); // On Windows 9x Beep doesn't work 
                // properly :(, better try on NT/2K/XP
   slp(500);
   f3(440,200); // returns a value, but the program
                // ignores it

   // default is no exceptions on missing entries
   int   nTRV;

   nTRV = foo(777);
   printf("default return value is %d\n", nTRV);

   // now we'll be throwing (exceptions) - and 
   // catching too
   foo.SetThrowExceptionOnMissingEntry(true);
   try {
      nTRV = foo(777);
      // never gets here
      printf("default return value is %d\n", nTRV);
   } catch ( int e ) {
      printf("exception #%02d caught\n", e);
   }
}

The classes can be further improved:

  • The thrown exceptions can be improved, the existing are just a sketch

  • Not only the load path, but also the DLL name can be different in the alternative variants

  • It can be made possible to manage different versions of the DLL

Please post your comments and improvements, or e-mail me.

Downloads

Download source - 8Kb



Comments

  • Short blog post uncovers the unquestionable details on gucci as well as how it can certainly harm your organization.

    Posted by emeseesip on 05/06/2013 03:13pm

    Essentially The Most Complete adidas Guide You Ever Seen Or else Your Money Back [url=http://www.guccija.biz/]gucci 財布[/url] Wow, remarkable product. People must consider nike immediately whilst it is still in stock ! ! [url=http://www.guccija.biz/]グッチ キーケース[/url] nike assists everybody by simply adding quite a few distinctive features and options. This is a unvaluable item for any supporter of nike. [url=http://www.guccija.biz/]グッチ ショルダーバッグ[/url] Impartial guide shows you Five fresh, new things on nike that no-one is speaking about. [url=http://www.chanelja.biz/]シャネル 財布[/url] The main reason why not a soul is speaking about adidas and things one should engage in this afternoon. [url=http://www.chanelja.biz/]シャネル 長財布[/url] Recent queries about adidas replied and consequently reasons why you should definitely look at every word on this article. [url=http://www.chanelja.biz/]chanel バッグ[/url] Fundamental principles of the nike that you could make use of starting off today.[url=http://www.nikeja.biz/]ナイキ[/url] Methods to discover every part there is to understand concerning gucci in three basic steps.

    Reply
  • Shorter piece of writing uncovers the proven info about gucci and also how it could cause problems for you.

    Posted by incockDak on 04/24/2013 10:24pm

    All new questions about nike resolved and as a result the reason why you must definitely look at every single statement of this post.[url=http://www.nikejpgolf.biz/]ナイキゴルフ[/url] A double take on nike [url=http://www.nikejpgolf.biz/nike-ゴルフボール-c-23.html]ナイキgolf[/url] Newbie questions about nike addressed in addition to reasons why you should go through every word of this specific story. [url=http://www.nikejpgolf.biz/nike-アイアン-c-1.html]ナイキゴルフ[/url] Unbiased page lets out Five completely new things over nike that not a soul is mentioning. [url=http://www.nikejpgolf.biz/nike-アイアン-c-1.html]nike ゴルフ[/url] I would say the nike Company Speak - Buyers who cares benefits? [url=http://www.nikejpgolf.biz/nike-ゴルフシューズ-c-15.html]nike sb[/url] Things and formation throughout Houston : mizuno has left without see you later [url=http://www.nikeyasuyi.com/]ナイキスニーカー[/url] Outfits and processing in Las Vegas, Nevada - mizuno has left with no farewell [url=http://www.nikeyasuyi.com/nikeナイキRunning-c-3.html]ナイキランニング[/url] Some of the nike Company Dialog - Members who cares about nothing wins?! [url=http://www.nikeyasuyi.com/nikeナイキDunk-c-9.html]nike dunk[/url] How the nike Enterprise Dialogue - Workers who likes pretty much nothing revenues? [url=http://www.nikeyasuyi.com/nikeナイキDunk-c-9.html]nike シューズ[/url] nike is giving completely new life to the old challenge-- gold measures

    Reply
  • Unique commentary will give you the simple truth around nike which only a few users are conscious of.

    Posted by icoppyapedcap on 04/24/2013 08:44pm

    GqvMxfFhsZph [url=http://www.nikeyasuijp.com/]ナイキ[/url]OtpZycExgZjb [url=http://www.nikeyasuijp.com/nike-air-force1エアフォース1-c-14.html]ナイキ エアフォース[/url]JvoGkoUfrVjm [url=http://www.nikeyasuijp.com/nike-air-maxエアマックス-c-12.html]ナイキ エアマックス[/url]FvjCcaEraZls [url=http://www.nikeyasuijp.com/nike-air-jordanエア-ジョーダン-c-13.html]nike free[/url]NjnWumXvfIeg

    Reply
  • How do i use the tool

    Posted by Legacy on 08/22/2002 12:00am

    Originally posted by: Cardian

    Cool Programm, but ...

    Waht make the 'Value'?
    Is Arguments without Return-Type?
    Is 'SetType' the Return-Type?

    THX

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • Due to internal controls and regulations, the amount of long term archival data is increasing every year. Since magnetic tape does not need to be periodically operated or connected to a power source, there will be no data loss because of performance degradation due to the drive actuator. Read this white paper to learn about a series of tests that determined magnetic tape is a reliable long-term storage solution for up to 30 years.

Most Popular Programming Stories

More for Developers

RSS Feeds