Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Partage des données entre deux exécutions d'une DLL

9 réponses
Avatar
Roger
Bon je n'avais pas compris au départ qu'entre deux exécutions d'une même dll
ça n'était pas forcément toujours la même image de la dll qui s'exécutait,
ce qui fait que d'une exécution à l'autre les données initialisées
dynamiquement n'étaient pas conservées. L'ayant finalement compris à mes
dépends je m'en suis sorti de manière brutale mais efficace en mettant les
données qui ont été modifiées et que je veux retrouver dans l'exécution
suivante dans un fichier que je sauvegarde en fin de chaque exécution et que
je relis en début de chaque exécution. Toutefois cette méthode qui marche
très bien est un peu bestiale et j'ai voulu trouver quelque chose de plus
standard, je me suis donc penché sur les segments et le mapping, mais pour
l'instant je n'ai pas dû tout comprendre.
Concernant les segments, j'ai testé deux trucs qui passent très bien en
compilation, mais je ne retrouve pas mes données d'une exécution à l'autre:
1er test:
#pragma section("Zonecommune",read,write,shared)
struct DETAIL // structure des données récupérables d'une exécution à
l'autre
{
<<<<<<<<< ici mes données à récupérer >>>>>>>>>>>>
}
#pragma data_seg("Zonecommune")
DETAIL Mesdonnees;
#pragma data_seg()

2ème test:
struct DETAIL // structure des données récupérables d'une exécution à
l'autre
{
<<<<<<<<< ici mes données à récupérer >>>>>>>>>>>>
}
#pragma data_seg("Shared")
DETAIL Mesdonnees;
#pragma data_seg()

Dans les deux tests, j'initialise Mesdonnees.toto, Mesdonnees.truc etc... au
premier passage et aux passages suivant les initialisations ont été perdues
! Fallait-il faire autre chose ??

Concernant le mapping, j'ai commencé à faire ceci:

HANDLE hdlemap;
LPVOID ptrmap;
hdlemap = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0,
longdetail, NULL);
ptrmap = MapViewOfFile(hdlemap, FILE_MAP_WRITE, 0, 0, 0);

Mais une fois que j'ai le pointeur sur la zone mappée (ptrmap), d'une part
je ne vois pas comment l'utiliser pour mettre mes données dedans, d'autre
part le ptrmap d'après ce que je comprends n'étant pas lui-même dans la zone
mappée, je ne vois pas comment le récupérer d'une exécution à l'autre ?
(sauf évidemment à le sauver dans un fichier, mais alors ça n'a plus
d'intérêt).

Merci

9 réponses

Avatar
Roger
Bon, vous fatiguez pas pour le mapping je pense avoir trouvé, en fait c'est
comme avec des fichiers, au lieu de copier des fichiers je fais un
copymemory. Confirmez seulement si c'est OK. Merci.
Par contre pour les segments je n'ai pas trouvé pourquoi ça ne marchait pas,
si quelqu'un sait......
Merci
Avatar
Christian ASTOR
Roger a écrit :

#pragma data_seg("Zonecommune")
DETAIL Mesdonnees;
#pragma data_seg()



Tu as notamment oublié ceci qui est important :

"Any variables in a shared data segment must be statically initialized."

cf.doc et KB associées (KB125677, ...) =>
http://msdn.microsoft.com/en-us/library/h90dkhs0(v=vs.80).aspx
Avatar
Roger
Tu as notamment oublié ceci qui est important :

"Any variables in a shared data segment must be statically initialized."

cf.doc et KB associées (KB125677, ...) =>
http://msdn.microsoft.com/en-us/library/h90dkhs0(v=vs.80).aspx



Effectivement, je ne vais pas assez souvent sur le site de microsoft,
j'avais pris l'exemple en ligne sur un site quelconque sur lequel le modèle
n'utilisait pas "static".
Merci encore.

PS. Si je peux me permettre une question subsidiaire, cette fois ci
concernant le mapping que j'ai réussi à faire fonctionner, mais donc
l'utilisation que j'en ai faite ne me paraît pas logique:
Voila, j'ai considéré au départ (sûrement à tort) que écrire ou lire dans un
fichier mémoire ça marchait comme read ou write sur un support disque
quelconque, c'est à dire qu'au début,
pour sauvegarder mes données je faisais (pour simplifier):
1.- hdlemap = CreateFileMapping((HANDLE)0xFFFFFFFF, .....,Mymapname);
2.- ptrmap = MapViewOfFile(hdlemap, ....);
3.- CopyMemory(ptrmap, &Mesdonnees,...);
4.- CloseHandle(hdlemap );
sachant que comme pour un fichier le CreateFileMapping est équivalent à un
OpenFileMapping si un fichier de même nom existe déjà.
Pour restorer mes données je faisais la même chose sauf l'instruction copy
qui était inversée:
1.- hdlemap = CreateFileMapping((HANDLE)0xFFFFFFFF, .....,Mymapname);
2.- ptrmap = MapViewOfFile(hdlemap, ....);
3.- CopyMemory(&Mesdonnees, ptrmap,...);
4.- CloseHandle(hdlemap );
Et je me suis aperçu que ça ne marchait pas, je ne récupérais pas mes
données, j'ai alors enlevé simplement l'instruction CloseHandle et
maintenant ça marche nickel, je récupère bien mes données. Cependant dans
cette procédure il y a quelque chose qui ne me paraît pas logique bien que
ça fonctionne, en effet du fait que j'ai enlevé l'instruction CloseHandle on
peut considérer que le mapping est resté ouvert, or à chaque entrée dans une
procédure de save ou de restore je suis amené à faire un CreateFileMapping
c'est à dire en fait l'équivalent d'un Open sur un fichier déjà ouvert ! il
y a quelque chose de dérangeant pour l'esprit et je suis étonné que le
système l'accepte !
Ai-je donc bien tout compris ? et est-ce bien ainsi qu'il faut procéder ?
Merci
Avatar
Roger
Concernant les segments, je viens de faire le test en remplaçant:
DETAIL Mesdonnees;
par:
static DETAIL Mesdonnees;

Mais ça ne marche toujours pas, il doit encore manquer quelque chose !
Avatar
Christian ASTOR
Roger a écrit :
Concernant les segments, je viens de faire le test en remplaçant:
DETAIL Mesdonnees;
par:
static DETAIL Mesdonnees;

Mais ça ne marche toujours pas, il doit encore manquer quelque chose !



"statically initialized", ça ne veut pas dire rajouter "static" :-)
Ça veut dire que les données doivent être initialisées dans le segment
(en "dur" quoi)...
Avatar
Christian ASTOR
Roger a écrit :

PS. Si je peux me permettre une question subsidiaire, cette fois ci
concernant le mapping que j'ai réussi à faire fonctionner, mais donc
l'utilisation que j'en ai faite ne me paraît pas logique:
Voila, j'ai considéré au départ (sûrement à tort) que écrire ou lire dans un
fichier mémoire ça marchait comme read ou write sur un support disque
quelconque,



Oui, c'est le même principe...
Voir les exemples de MS comme FCopy.Cpp, Producer.Cpp, ou la doc :
http://msdn.microsoft.com/en-us/library/aa366551(v=vs.85).aspx
Avatar
Roger
"statically initialized", ça ne veut pas dire rajouter "static" :-)
Ça veut dire que les données doivent être initialisées dans le segment (en
"dur" quoi)...



Ok, merci. Mais dans ce cas les segments ça n'est pas intéressant dans mon
cas, car il y a une donnée qui est fournie à la dll (qui a besoin de
partager les données) par le programme principal. Dans la dll je ne connais
pas la valeur de cette donnée avant que le prog ppal appelle la première
fonction de la dll (il passe cette donnée en paramètre lors de l'appel).
J'en conclus que dans mon cas il n'y a que le mapping qui marche ou
l'utilisation brutale d'un fichier de travail.
A+
Avatar
Roger
Oui, c'est le même principe...
Voir les exemples de MS comme FCopy.Cpp, Producer.Cpp, ou la doc :
http://msdn.microsoft.com/en-us/library/aa366551(v=vs.85).aspx



Merci, je vais aller voir ça
A+
Avatar
Roger
Oui, c'est le même principe...
Voir les exemples de MS comme FCopy.Cpp, Producer.Cpp, ou la doc :
http://msdn.microsoft.com/en-us/library/aa366551(v=vs.85).aspx



Merci, j'ai regardé mais j'ai aussi continué à faire des tests, si ça
t'intéresse, voici le résultat:
J'ai remplacé systématiquement le createfilemapping par un openfilemapping
et je ne fais le createfilemapping que si le openfilemapping échoue et dans
ce cas je conserve bien mes données dans la mémoire mappée même en
réintroduisant les closehandle !
Il semblerait donc la conclusion que ces tests ont l'air de démontrer soit
la suivante:
Les closehandle ne seraient pas en cause, ils ne feraient pas perdre la
mémoire mappée. Le problème viendrait uniquement du createfilemapping qui
fonctionnerait de la manière suivante:
1.- lorsqu'on fait un createfilemapping sur un nom de fichier
createfilemapping(toto,....) il se comporterait effectivement comme un
createfile(toto,....), c'est à dire que si le fichier existe déjà le
createfilemapping devient équivalent à un openfilemapping.
2.- Par contre lorsqu'on fait un createfilemapping pour de la mémoire, même
avec un nom d'objet map: createfilemapping(0xFFFF,....,mamap), il aurait
deux comportement différents selon que la map a été ou non fermée par
closehandle.
2.1.- si la map n'a pas été fermée, comme le createfile il est équivalent à
un openfilemapping.
2.2.- si la map a été fermée par un closehandle, il recrée une nouvelle zone
de mapping vierge avec le même nom de map, mais la faute n'est pas à imputer
au closehandle puisque lorsque je remplace le createfilemapping par un
openfilemapping je retrouve bien la zone qui contient mes données et qui
avait pourtant été fermée précédemment par un closehandle.
A+