2010-10-02 4 views
1

J'écris une bibliothèque proxy (appelée Library A) qui est juste une interface avec une autre DLL (appelée Library B) qui peut être présente ou non sur le système. L'idée est qu'un programme serait lié à cette bibliothèque A au lieu de la bibliothèque originale B; et la bibliothèque A gérerait les erreurs si la bibliothèque B n'était pas installée sur le système.Empêcher trop de LoadLibrary/FreeLibrary

donc une fonction typique proxy ressemblerait à ceci:

int function(int arg1, int arg2) 
{ 
    HINSTANCE hinstLib; 
    UINT errormode = SetErrorMode(SEM_FAILCRITICALERRORS); 
    SetErrorMode(errormode | SEM_FAILCRITICALERRORS); 
    hinstLib = LoadLibrary(TEXT(ORIGINAL_DLL)); 
    SetErrorMode (errormode); 
    if (hinstLib != NULL) 
    { 
     ProcAdd = (void *) GetProcAddress(hinstLib, TEXT("function")); 
     if (NULL != ProcAdd) 
     { 
      return (ProcAdd) (arg1, arg2); 
     } 
     FreeLibrary(hinstLib); 
    } 
    return ERROR; 
} 

Maintenant, je ferais cela pour toutes les entrées originales dans la bibliothèque B. Il pourrait y avoir beaucoup d'appels à elle. Donc, charger/décharger la DLL si fréquemment va certainement avoir un impact sur la vitesse.

Je me demandais s'il serait acceptable d'utiliser une variable globale hinstLib; quelque chose comme

HINSTANCE hinstLib = LoadLibrary(TEXT(ORIGINAL_DLL)); 

int function(int arg1, int arg2) 
{ 
    if (hinstLib != NULL) 
    { 
     ProcAdd = (void *) GetProcAddress(hinstLib, TEXT("function")); 
     if (NULL != ProcAdd) 
     { 
      return (ProcAdd) (arg1, arg2); 
     } 
    } 
    return ERROR; 
} 

Et laissez Windows télécharge automatiquement la DLL lorsque les sorties du programme (en supposant qu'il ne le décharger).

Merci d'avance pour vos remarques sages ...

Jean-Yves

Répondre

2

À moins que le déchargement est notamment le cas d'utilisation, alors cela est bien beau. Cependant, je voudrais mettre en œuvre une certaine sécurité de thread pour s'assurer qu'il n'y a pas de conditions de course à travers ce code en utilisant un Critical Section.

Ceci est par exemple simillar à celui de l'article wikipedia

/* Sample C/C++, Windows, link to kernel32.dll */ 
    #include <windows.h> 

    static CRITICAL_SECTION cs; 

    static HINSTANCE hinstLib = LoadLibrary(TEXT(ORIGINAL_DLL)); 

    /* Initialize the critical section before entering multi-threaded context. */ 
    InitializeCriticalSection(&cs); 

    void f() { 
     /* Enter the critical section -- other threads are locked out */ 
     __try { 
      EnterCriticalSection(&cs); 

      if (hinstLib != NULL)  { 
      ProcAdd = (void *) GetProcAddress(hinstLib, TEXT("function")); 
     } __finally { 
      LeaveCriticalSection(&cs); 
     } 
     if (NULL != ProcAdd) { 
       return (ProcAdd) (arg1, arg2); 
     } 
    } 

. 
. 
. 

    /* Release system object when all finished -- usually at the end of the cleanup code */ 
    DeleteCriticalSection(&cs); 
+0

C'était rapide .. Je ne peux pas ajouter facilement un code de nettoyage cependant; parce que je ne veux pas modifier en aucune façon le code original qui appelait la bibliothèque B (et appellera maintenant la bibliothèque A). Si je pouvais, j'aurais fait la FreeLibrary là .. – jyavenard

+0

Utiliser pthreads.h et le verrouillage serait trivial pour empêcher les conditions de course. Besoin de savoir si des API similaires existent sous Windows. Je ne suis pas un expert Windows. – jyavenard

+0

voir ici http://stackoverflow.com/questions/2150938/can-i-get-cs-pthread-h-to-compile-in-windows –