J'ai une dll avec un point d'entrée "Compute" disons.
Pour la charger depuis un programme, j'utilise LoadLibrary, puis GetProcAdress, et je lance la fonction... ça marche.
Maintenant, je fais des threads avec CreateThread, et je lance donc en parallèle plusieurs fois ma fonction Calcul : ça crash. En débuggant, je vois qu'il y a des variables globales qui ont des valeurs mauvaises : et oui... dans la dll, il y a des variables globales et autres joyeusetés du genre...
Du coup, j'essaie, dans chaque thread, de faire un LoadLibrary en espérant que les contextes mémoire seront séparés, comme des processus. Non. Même genre de crashs.
Si je crée un EXE simple qui ne fait que lancer la dll (enfin la fonction Compute), et que j'appelle cet exe depuis mes threads avec CreateProcess, ça marche, ce sont des processus distincts avec chacun leur contexte mémoire, donc ok.
Mais j'aimerais éviter de trimballer un exe externe.
Existe t il un moyen de charger une dll avec son propre contexte mémoire, quit à la charger plusieurs fois en parallèle ? Ou bien de faire en sorte que CreateProcess ne lance non pas un exe, mais un point d'entrée de dll ?
Lancer une fonction de dll comme un processus indépendant.
Edit: Il y a pas mal d'optimisations possibles si tu charges beaucoup de fois la DLL, tu pourrais minimiser le coup de la construction la table d'import, l'initialisation des sections TLS.
Existe t il un moyen de charger une dll avec son propre contexte mémoire, quit à la charger plusieurs fois en parallèle ? Ou bien de faire en sorte que CreateProcess ne lance non pas un exe, mais un point d'entrée de dll ?
Lancer une fonction de dll comme un processus indépendant.
(dernière réponse david efferman), la solution la plus "simple" serait éventuellement de creer des copies temporaire de la dll (en la renommant donc) et d'y acceder va loadlibrairy/getprocadress? (Le commentaire associé -msalters- j'ai pas compris mais semble une bonne idée )
** La doc, c'est comme le PQ: ça sert à se démerder tout seul **
Merci pour vos réponses, en effet, après quelques recherches, un LoadLibrary de la même dll plusieurs fois dans le même processus ne charge pas plusieurs fois la dll, mais une seule fois. Et donc les variables globales posent un vrai soucis.
La solution la plus simple est effectivement de faire des copies de la dll, pour leurer Windows, lui dire que c'est 2 dll distinctes, ou alors sinon, reprogrammer un loader complexe comme proposé, mais ça nous emmène loin.
Je crois que je vais voir pour faire autrement, quit a faire du multiprocessus. Merci a vous !
A titre informatif, j'avais codé une version simplifiée de ce que je veux, je poste les codes.
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
typedef void (*Func)();
unsigned long WINAPI onethread(void* params)
{
Func f;
int param;
HMODULE H;
param = *(int*)(params);
if (param==1)
H = LoadLibrary(L"d:\\fred\\testdll\\ladll\\release\\ladll.dll");
else
H = LoadLibrary(L"d:\\fred\\testdll\\ladll\\Release\\ladll.dll");
if (H==NULL)
return -1;
f = (Func)GetProcAddress(H,"Test");
if (f==NULL)
return -1;
Sleep(30);
f();
Sleep(1000);
FreeLibrary(H);
return 0;
}
int main()
{
HANDLE T1,T2;
int a,b;
a=1;
b=2;
T1 = CreateThread(NULL,0,onethread,&a,0,0);
Sleep(12);
T2 = CreateThread(NULL,0,onethread,&b,0,0);
Sleep(2000);
return 0;
}
Les résultats sont 0022, ce qui montre que la variable globale est la même. Si je change une ligne dans le 2e LoadLibrary en appelant ladll2.dll, alors j'ai bien 0011, mais que dans ce cas.
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html