OVH Cloud OVH Cloud

dll allocation memoire et desallocation ailleurs

16 réponses
Avatar
dark poulpo
(C++)

bonjour,
voila, jai un programme qui charge une dll, et qui appele une de ses api
allouant de la memoire et fait plein de travaux.
ex:

unsigned char *data;
api(&data);

seulement voila, je voudrais que mon programme puisse desallouser la memoire
allouer par la dll, mais un simple delete [] data; ne marche pas , hors je
ne voudrais pas que ma dll le desalloue elle pour d'autre raison de
traitement.

(l'allocation de la memoire dans la dll se fait pas new , et je ne peux pas
allouer la memoire avant l'appel de l'api car c'est elle qui sait combien il
faut allouer et qui m'initialise le contenu de la mémoire, et cet api peut
desallouer aussi la memoire en cas d'erreur)

je voudrais savoir si ya une api win qui permet de desallouer la memoire ?
sinon jai pensé a fournir un pointeur de fonction a l'appel de l'api pour
que celle-ci se charge de l'allocation (afin d'avoir une adresse accessible
par mon exe pour le delete)

je cherche un moyen qui soit propre
merci d'avance


--
-----
http://dark.freezee.org/
- Dark Update v1.0
- Dark Emule v0.44b r4
- Dark 3D-X (le desktop 3d pour windows) (en cours)

10 réponses

1 2
Avatar
Vincent Burel
Hello sombre poulpe ! :-)

Alors, retenez que les moyens propres, sont souvent les plus simples, et
ceux qui suivent une logique d'organization. Notamment si celui qui crée est
celui qui détruit, celui qui alloue est celui qui libère.

Si vous être capable d'appeler une fonction de votre DLL qui alloue de la
mémoire ou bien crée divers object pour faire ceci ou cela. Vous serez
capable d'appeller une fonction de cette DLL qui s'occupera de libérer cette
mémoire et de détruire les éventuels object créés ci-avant...

unsigned char *data;
myapi_create(&data);
myapi_destroy(data);

notez que généralement on écrit plutot sous cette forme :

unsigned char *lpdata;
lpdata= myapi_create(...);
myapi_destroy(lpdata);

Sinon l'allocation mémoire peut se faire en utilisant directement les
service du système : voir LocalAlloc, GlobalAlloc, HeapAlloc etc... sinon
malloc c'est bien aussi...

VB


"dark poulpo" wrote in message
news:41f65f8b$0$19414$
(C++)

bonjour,
voila, jai un programme qui charge une dll, et qui appele une de ses api
allouant de la memoire et fait plein de travaux.
ex:

unsigned char *data;
api(&data);

seulement voila, je voudrais que mon programme puisse desallouser la


memoire
allouer par la dll, mais un simple delete [] data; ne marche pas , hors je
ne voudrais pas que ma dll le desalloue elle pour d'autre raison de
traitement.

(l'allocation de la memoire dans la dll se fait pas new , et je ne peux


pas
allouer la memoire avant l'appel de l'api car c'est elle qui sait combien


il
faut allouer et qui m'initialise le contenu de la mémoire, et cet api peut
desallouer aussi la memoire en cas d'erreur)

je voudrais savoir si ya une api win qui permet de desallouer la memoire ?
sinon jai pensé a fournir un pointeur de fonction a l'appel de l'api pour
que celle-ci se charge de l'allocation (afin d'avoir une adresse


accessible
par mon exe pour le delete)

je cherche un moyen qui soit propre
merci d'avance


--
-----
http://dark.freezee.org/
- Dark Update v1.0
- Dark Emule v0.44b r4
- Dark 3D-X (le desktop 3d pour windows) (en cours)




Avatar
dark poulpo
merci, mais jai un autre probleme maintenant, la dll que j'utilise c 'est
une dll tiré parmis une liste de dll compatible avec ce qui doit etre
chargé. ( en gros c'est un plugin ), mais bon jai deja fait ce que tu ma
dis.

actuellement le principe se passe comme ca.

jappele le manageur qui se charge de voir quelle dll doit etre utilisé pour
charger les datas, la dll les charge et renvoi ca au manageur qui corrige
les erreurs possible pour etre compatible a 100% et renvoi tout ca a
l'apellant.

problemes :
- je me vois pas relister toute les dll pour savoir quelle est celle qui a
chargé les datas
- je me vois pas sauver l'instance de la dll et la fournir avec la reponse,
car on peut en cours decharger la dll, donc linstance serait foireuse
Avatar
dark poulpo
jai une idee, le manageur crée une zone memoire et recopie celle donnée
dedans, et desalloue l'autre. :-)
Avatar
Arnaud Debaene
dark poulpo wrote:
(C++)

bonjour,
voila, jai un programme qui charge une dll, et qui appele une de ses
api allouant de la memoire et fait plein de travaux.
ex:

unsigned char *data;
api(&data);

seulement voila, je voudrais que mon programme puisse desallouser la
memoire allouer par la dll, mais un simple delete [] data; ne marche
pas , hors je ne voudrais pas que ma dll le desalloue elle pour
d'autre raison de traitement.



Solution la plus simple : compiler tous les modules de l'application (DLLs
et EXE) afin qu'ils utilisent la *même* version DL de la CRT : autrement dit
soit compiler tous les modules avec le flag /MDd (debug), soit tous avec le
flag /MD (release).
De cette manière, tous les modules utilisent le même manager mémoire de la
CRT, et tu peux librement allouer dans un module et désallouer dans l'autre.

C'est aussi la solution indispensable dès que tu passe entre modules des
objets qui font de l'allocation mémoire dans ton dos, comme std::string ou
std::vector par exemple.

Arnaud
MVP - VC
Avatar
Olivier Huet
Bonjour,

dark poulpo a écrit :
jai une idee, le manageur crée une zone memoire et recopie celle donnée
dedans, et desalloue l'autre. :-)



Oui c'est plus propre.

Sinon, tu pourrais aussi faire des chose de ce genre :

- Tes deux portion d'application peuvent utiliser une même dll
"allocateur",

- Ton manageur fournit des fonctions de callback a ses plugins pour
allouer/desalouer (c'est fréquent, dans les logiciels par plugins : il
me semble qu'il y avait ça dans les plugin Netscape, par exemple).

- ...

Mais dans l'absolu, si tu veux absolument faire ce que tu demandais dans
ton post initial, il y a tout de même une solution un peu "crade" mais
parfois acceptable : tu compiles les deux applications en configurant la
librairie C et C++ comme DLL : dans VS 6 et 2003, c'est dans les
paramètres de "C / C++", "code generation", puis "runtime library".

Via ce mécanisme, tu déportes toutes les allocations / désalocations
dans l'instance de la librairie c qui est justement chargée en dll (en 1
exemplaire).

ATTENTION, du coup, tes exe et dll dépenderont de msvcrt.dll et
probablement aussi msvcp60.dll (lib C++) si tu es avec visual studio 6,
et de dll avec des 7 quelque-part (msvcrt7.dll ou qqch comme ça) si tu
es avec visual studio 2003.
--> il faut donc peut-être les redistribuer avec ton application.


Olivier Huet
Avatar
Arnaud Debaene
Olivier Huet wrote:
Bonjour,

dark poulpo a écrit :
jai une idee, le manageur crée une zone memoire et recopie celle
donnée dedans, et desalloue l'autre. :-)



Oui c'est plus propre.

Sinon, tu pourrais aussi faire des chose de ce genre :

- Tes deux portion d'application peuvent utiliser une même dll
"allocateur",

- Ton manageur fournit des fonctions de callback a ses plugins pour
allouer/desalouer (c'est fréquent, dans les logiciels par plugins : il
me semble qu'il y avait ça dans les plugin Netscape, par exemple).

- ...

Mais dans l'absolu, si tu veux absolument faire ce que tu demandais
dans ton post initial, il y a tout de même une solution un peu
"crade" mais parfois acceptable



En quoi est-ce "crade" exactement selon toi?

C'est la seule solution valable si tu manipule des objets qui font de
l'alloccation en interne et que tu les passe par valeur entre modules.

Arnaud
MVP - VC
Avatar
dark poulpo
> Solution la plus simple : compiler tous les modules de l'application (DLLs
et EXE) afin qu'ils utilisent la *même* version DL de la CRT : autrement


dit
soit compiler tous les modules avec le flag /MDd (debug), soit tous avec


le
flag /MD (release).
De cette manière, tous les modules utilisent le même manager mémoire de la
CRT, et tu peux librement allouer dans un module et désallouer dans


l'autre.

tu veux dire que mon probleme etait parceque mon exe etait en debug et mes
dll en release?

je garde ce concept sous la main, parceque la jai deja recodé tout, mais ca
peut me servir.

merci
Avatar
Arnaud Debaene
dark poulpo wrote:
Solution la plus simple : compiler tous les modules de l'application
(DLLs et EXE) afin qu'ils utilisent la *même* version DL de la CRT :
autrement dit soit compiler tous les modules avec le flag /MDd
(debug), soit tous avec le flag /MD (release).
De cette manière, tous les modules utilisent le même manager mémoire
de la CRT, et tu peux librement allouer dans un module et désallouer
dans l'autre.



tu veux dire que mon probleme etait parceque mon exe etait en debug
et mes dll en release?



Eventuellement : quels sont les flags de compilation des différents modules
dans l'onglet Code Generation/Runtime Library ?

Remarques bien que si tu veux avoir un module en release et l'autre en
debug, tu peux très bien compiler une version release avec /MDd ou une
versiob debug avec /MD.

je garde ce concept sous la main, parceque la jai deja recodé tout,
mais ca peut me servir.



Dès que tu fais de l'objet avec plusieurs modules, c'est quasi
indispensable.

Arnaud
MVP - VC
Avatar
Olivier Huet
Bonjour,

Arnaud Debaene a écrit :
Olivier Huet wrote:
Mais dans l'absolu, si tu veux absolument faire ce que tu demandais
dans ton post initial, il y a tout de même une solution un peu
"crade" mais parfois acceptable




En quoi est-ce "crade" exactement selon toi?

C'est la seule solution valable si tu manipule des objets qui font de
l'alloccation en interne et que tu les passe par valeur entre modules.



En fait, je ne trouve pas *la résolution* crade, mais le fait de devoir
le faire : cela est généralement dû à un mauvais cloisonnement entre les
modules. Mais c'est plus une impression qu'un argumentaire.

De plus, j'ai tendance à préférer les modules :

- soit avec des interfaces simples (fonction C avec des arguments à la
Win32)
- soit avec des structure complexes, mais à condition d'avoir un runtime
qui les marshale (COM, DCOM, CORBA, ...).

--> dans ce style d'interfaces, on n'a pas ce problème.


De plus, pour le déploiement des dll de la libc et la libc++, c'est
problématique si les postes client ne sont pas complètement contrôlés,
ou si le déploiement est complèxe (là c'est du vécu : chat échaudé
craint l'eau froide).


Olivier Huet
Avatar
Vincent Burel
"dark poulpo" wrote in message
news:41f699b0$0$2185$
merci, mais jai un autre probleme maintenant, la dll que j'utilise c 'est
une dll tiré parmis une liste de dll compatible avec ce qui doit etre
chargé. ( en gros c'est un plugin ), mais bon jai deja fait ce que tu ma
dis.

actuellement le principe se passe comme ca.

jappele le manageur qui se charge de voir quelle dll doit etre utilisé


pour
charger les datas, la dll les charge et renvoi ca au manageur qui corrige
les erreurs possible pour etre compatible a 100% et renvoi tout ca a
l'apellant.

problemes :
- je me vois pas relister toute les dll pour savoir quelle est celle qui a
chargé les datas
- je me vois pas sauver l'instance de la dll et la fournir avec la


reponse,
car on peut en cours decharger la dll, donc linstance serait foireuse



si vous faites une gestion de plug-in vous devez inéluctablement vous
occuper de
- charger / décharger les DLL en mémoire et donc gérer un HMODULE pour
chaque DLL.
- pour chacun de ces module vous devez gérer la collection d'object
éventuellement créer pour pouvoir la détruire.

Et à tout moment, vous devez savoir :
- combien d'object sont crée (la collection d'objet)
- de quel DLL ces object sont issus.
- quel DLL est en mémoire et combien d'objet fait référence à chaque DLL.

C'est comme ca qu'il faut gérer du HOSTING de PLUG-IN et c'est pas
autrement.

REM : je le dis depuis des années ici comme ailleurs, pour programmer il
faut savoir gérer de la donnée. gérer de la donnée ca veut dire être capable
de créer / détruire / trier / modifier / et lier des collections d'objets.
Sans cela, rien n'est possible.

VB

PS : l'essentiel des programmeur du dimanche
1 2