c ++ - At have flere forekomster af globale variabler fra samme DLL

Indlæg af Hanne Mølgaard Plasc

Problem



I øjeblikket har jeg et system med følgende forenklede visning.


The entire system run under single process
------------------------------------------
       --- DLL0.DLL --- COMMON.DLL (contains global\_variable in COMMON.DLL)
EXE ---|
       --- DLL1.DLL --- COMMON.DLL (contains global\_variable in COMMON.DLL)





Kildekoden for COMMON.DLL er som følger.


// COMMON.DLL
#ifdef COMMON\_EXPORTS
\_declspec( dllexport ) int global\_variable = 100;
// Function used to access and print global\_variable.
\_\_declspec(dllexport) void common\_fun\_which\_access\_global\_variable();
#else
\_declspec(dllimport) int global\_variable;
\_\_declspec(dllimport) void common\_fun\_which\_access\_global\_variable();
#endif


Kilden til DLL0.DLL er som følger.


\_\_declspec(dllexport)
void DLL0() {
    printf ("This is DLL0
");
    printf ("In DLL0, global\_variable is \%i
", global\_variable);
    common\_fun\_which\_access\_global\_variable();
    global\_variable = 200;
    printf ("DLL0 is now setting global\_variable to 200
");
    common\_fun\_which\_access\_global\_variable();
}


Kilden til for DLL1.DLL er som følger.


\_\_declspec(dllexport)
void DLL1() {
    printf ("This is DLL1
");
    printf ("In DLL1, global\_variable is \%i
", global\_variable);
    common\_fun\_which\_access\_global\_variable();
    global\_variable = 400;
    printf ("DLL1 is now setting global\_variable to 400
");
    common\_fun\_which\_access\_global\_variable();
}


Kildekode for EXE er som følger.


HINSTANCE instance0 = AfxLoadLibrary(\_T("DLL0.dll"));
FARPROC fun0 = GetProcAddress(instance0, "DLL0");
HINSTANCE instance1 = AfxLoadLibrary(\_T("DLL1.dll"));
FARPROC fun1 = GetProcAddress(instance1, "DLL1");
\_fun0();
\_fun1();





Udgangen er som følger.


This is DLL0
In DLL0, global\_variable is 100
In COMMON, global\_varialbe is 100
DLL0 is now setting global\_variable to 200
In COMMON, global\_varialbe is 200

This is DLL1
In DLL1, global\_variable is 200    <-- I wish 100 is being printed.
In COMMON, global\_varialbe is 200  <-- I wish 100 is being printed here too.
                                   <-- I wish DLL0 and DLL1 have their own instance of
                                   <-- global\_variable respectively.
DLL1 is now setting global\_variable to 400
In COMMON, global\_varialbe is 400





Hele systemet udføres i en enkelt proces. Selvom DLL0.DLL og DLL1.DLL indlæses eksplicit hver, vil afhængigheden COMMON.DLL kun blive indlæst en gang i hele programmets livscyklus. EXE vil ikke indlæse samme COMMON.DLL to gange.


Er der nogen måde, kan jeg opnå følgende uden at krænke en af ​​reglerne?



  1. DLL0 og DLL1 kan have deres egen forekomst af global\_variable?

  2. global\_variable skal være global og genindsættes COMMON.DLL?

  3. COMMON.DLL vil blive indlæst gennem implicit linking ved hjælp af LIB-fil.

  4. Ingen omdøbning COMMON.DLL til COMMON-DLL0.DLL og COMMON-DLL1.DLL.

  5. Ingen statisk forbindelse.

  6. Hvis DLL0 ændrer værdien af ​​global\_variable, skal common\_fun\_which\_access\_global\_variable fra DLL0 få adgang til DLL0s ændrede værdi. Men at kalde common\_fun\_which\_access\_global\_variable fra DLL1 bør ikke forstå ændringerne.



** Jeg ved, at dette er for meget. Men jeg behandler nu en arvskode. Du ved :)


Vil side om side montering kunne løse denne slags problem? Hvad jeg forstår er, at side om side montering bruges til at løse flere DLL med samme navn men forskellige versionsproblemer. Jeg er ikke sikker på, om det er relevant i min ovennævnte sag?


Eller skal jeg spørge omvendt? Hvordan kan vi have 2 forekomster af COMMON.DLL indlæst inden for samme EXE?

Bedste reference


Hvis jeg forstår situationen korrekt, er COMMON.dll arvenskoden, og arvenskoden bruges af både DLL0.dll og DLL1.dll.


Uden at kende alle detaljerne foreslår jeg følgende:


1) Opret en global variabel i DLL0.dll og DLL1.dll.

2) Initialiser hver global variabel fra trin 1 med COMMON.dll 's global\_variable værdi.

3) Brug de to nye global\_variables efter behov.

Andre referencer 1


Da DLL'er har et enkelt og ensartet billede pr. Proces, er den eneste måde jeg kan se for at gøre, hvad du beder om, at flytte COMMON.dll til en unik proces pr. Brug. Det kunne gøres på forskellige måder, afhængigt af hvilken kode du har adgang til, og din tolerance for grimhed.


Kan din DLL0 og DLL1 blive omskrevet for at interagere med din COMMON.dll via en wrapper? Hvis det er tilfældet, har wrapper en separat proces til at interagere med common.dll. Indpakningen bruger derefter en form for IPC (måske delt delhukommelse) til at kommunikere med arbejdsprocessen.


Det er selvfølgelig langt mere kompliceret, at du bare kopierer common.dll til et nyt navn ... er du sikker på, at det er værd at smerte?

Andre referencer 2


Jeg havde dette nøjagtige problem, hvor jeg ikke havde kontrol over 3. part DLL0, DLL1 eller COMMON.


Løsningen jeg oprettede var at duplikere COMMON med forskellige navne, og at patch DLL0 og DLL1 for at indlæse deres egne kopier.


(i mit tilfælde måtte jeg køre mange kopier af 'DLL0' -niveauet, så skrev et program, der duplicerede 'DLL0' og 'COMMON' for hver forekomst, jeg havde brug for, og patched 'DLL0' -kopierne til det nye navn på Fælles. De nye navne skulle være lige så lange som originalen, og fra hukommelsen var det bare en søgning og erstatning af den specifikke navnetekst, selvom der var ANSI- og WIDE-sorter fra hukommelsen. Selvfølgelig kan denne fremgangsmåde ikke længere fungere, hvis DLL'erne er underskrevet?)