Bonjour à tous
Comment fait t'on pour mappé un fichier en mémoire avec l'api
createfilemapping, openfilemapping, mapviewoffile.
et surtout comment ecrire et lire des données dans ce fichier
merci d'avance
philippe Drapeau
Bonjour à tous
Comment fait t'on pour mappé un fichier en mémoire avec l'api
createfilemapping, openfilemapping, mapviewoffile.
et surtout comment ecrire et lire des données dans ce fichier
merci d'avance
philippe Drapeau
Bonjour...
Pourquoi veux tu utilisé des fichier mappés en mémoire (via l'API M$), alors que travailler avec la VCL et les Stream (TMemoryStream, TFileStream etc...) est si facile 8)
Cordialement
Salut,
L'utilisation des fichiers mapés en mémoire fait en général l'objet d'un chapitre complet dans les bouquins, mais on peut toujours essayer de te donner quelques indications ...
En supposant que tu veux utiliser ce système pour stocker des données en mémoire, tu dois tout d'abord appeler l'API CreateFileMapping en lui passant comme paramètres :
- $FFFFFFFF pour HFile
- Nil pour LpFileMappingAttributes
- Page_ReadWrite pour FlProtect
- 0 pour DwMaximumSizeHigh
- La taille souhaitée (ex : 2000) pour DwMaximumSizeLow
- PChar('UnNomDeFichier') pour LpName
Bien entendu, tu remplaces "UnNomDeFichier" par la chaîne qui te convient.
A partir de là, tu récupère un handle dont tu testes la validité en vérifiant qu'il est différent de 0. Ensuite, tu appelles MapViewOfFile en lui passant comme paramètres :
- le handle obtenu précédemment pour HFileMappingObject
- File_Map_Write pour DwDesiredAccess
- 0 pour DwFileOffsetHigh
- 0 pour DwFileOffsetLow
- la taille de ton fichier (utilisée ci-dessus) pour DwNumberOfBytesToMap
Tu obtiens en retour un pointeur non typé (Pointer) sur un bloc de N octets (la taille du fichier) dans lequel tu peux lire / écrire des informations comme tout autre bloc mémoire.
Une fois terminé, tu n'oublies pas de réinitialiser tout ceci en appelant :
- UnmapViewOfFile pour libérer le bloc mémoire
- CloseHandle pour le handle sur le fichier mapé
Ceci est une version très simplifiée du processus, mais elle devrait te permettre de procéder aux premiers tests. Personnellement, j'ai recours à ce type de fichier pour traiter des matrices financières (plans d'amortissement) dont certaines dépassent les 60 Mo ... et ça fonctionne sans problème.
Par ailleurs, j'ai été (agréablement) surpris par la rapidité d'accès aux données, car je pensais dans un premier temps que ce système était plutôt lent.
Ce que je peux te conseiller, c'est de stocker tout ceci dans une unité, sous forme d'une classe objet que tu pourras appeler ensuite ou surcharger trés facilement. Ceci te permet de disposer d'un objet bloc de mémoire d'un seul tenant.
J'aurais bien voulu te passer l'unité dans laquelle j'ai créé ce type de composant, mais comme il s'agit d'une bibliothèque reposant sur tout un tas d'interfaces, c'est à vrai dire assez difficile d'en extraire un simple bout de code. De plus, il se poserait des problèmes de copyright avec la boîte qui m'emploie ... donc, dommage mais tu peux débuter avec les infos ci-dessus.
Si tu veux approfondir le sujet, jettes un oeil dans l'aide en ligne des API et essaies d'acquérir un bouquin traitant du sujet, car il est un peu ardu au début et ce n'est pas très facile d'en expliquer tous les contours au travers d'un forum.
Bon courage,
A+
Didier
Bonjour
Merci à Didier et à françois Robert pour leurs reponses rapide.
Pour repondre à françois:
je veux utiliser les api pour communiquer entre un service et un programme trayicon.
par contre je ne connais pas le tmemoystream et le tfilestream, mais je vais regarder ca de plus près.
Pour repondre à didier:
La création avec createfilemapping ne me pose plus de probleme, ni la création de la vue avec mapviewoffile.
ce qui me pose un gros pb actuellement c'est l'uitilisation du pointer non typé fourni par mapviewoffile.
par contre ta reponse m'a apporté un eclaircissement sur, le fonctionnement du bazarre.
pour résumé, il n'y a que la perseverence qui paye, donc cela marchera forcement... un jour.
Philippe Drapeau
Salut,
Tu as raison, c'est à force de planter la machine et de redémarrer que l'on parvient à comprendre les choses ...
Concernant le pointeur non typé, en fait il s'agit d'une adresse mémoire "pointant" vers un bloc de données. Tu peux donc stocker tout un tas de choses aussi variées que des Integer, des String, des Float, ou du binaire pur et dur.
Lorsque tu as stocké, par exemple, une String, rien ne t'empêche d'accéder à cette chaîne alpha en transtypant ton pointeur initial en PChar.
Exemple (en supposant que Buffer est ton pointeur mapé et soit au moins aussi grand que la longueur d'une chaîne alpha + 1 caractère) :
FillChar(Buffer^,Succ(Length(MaChaine)),0) ;
Move(MaChaine[1],Buffer^,Length(MaChaine)) ; // Transfert données
ShowMessage(PChar(Buffer)) ;
Ca marche ... et dans ce cas tu as stocké un tampon alphanumérique (ou plus précisément une chaîne AZT puisqu'elle se termine par un #0). L'instant d'après, tu peux tout aussi bien transférer un Extended à la place de ton PChar ... d'où l'intérêt des blocs mémoire et des pointeurs (outre leur vitesse).
J'ai utilisé les fichiers mapés en mémoire pour implémenter un objet permettant de stocker des données polymorpes (string, dates, booléens, etc ...) et d'y accéder soit par indice, soit par une clé alpha. Pour cela, le bloc mémoire global (pointeur Buffer) est réutilisé par petits bouts pour stocker chaque composante en fonction de son type.
A partir de là, l'utilisateur n'a plus à se soucier de la notion de pointeur et peut écrire :
MonBloc.WriteString(0,'MaChaine') ;
MonBloc.WriteInteger(0,100) ;
MonBloc.WriteFloat(0,4.5) ;
etc ...
pour stocker successivement une chaîne alpha, un entier puis un flottant dans le même "sous bloc" mémoire situé en position 0.
C'est approximativement le même principe que les variants (beurk !!!), mais plus adapté à mes propres besoins et surtout avec une vérification de type par le compilateur ... ce qui est très appréciable. J'avoue avoir une sainte horreur des variants et ne les utiliser que si j'y suis obligé (objets COM notamment).
Par contre, ce type de programmation peut être effectué en utilisant des blocs de mémoire traditionnels (ReallocMem, GetMem) ou des flux mémoire (TMemoryStream). Le fichier mapé n'est en effet nullement obligatoire, mais il présente pas mal d'avantages notamment lorsque les blocs potentiellement alloués sont de très grande taille.
Si tu estimes devoir approfondir la notion de pointeurs non typés, il me semble avoir vu sur ce site un tutoriel traitant justement des pointeurs ...
Vérifie si l'article en question est toujours disponible, car c'est une technique trés intéressante pour gagner en vitesse d'exécution. Par contre, faut être extrêmement précis lors de la programmation (allocation des blocs, accès à l'octet prés, décalage des pointeurs), car les pointeurs ne supportent aucun "a peu près" de la part d'un programmeur ... sinon plantages assurés et crise de nerf pour chercher le bug qui tue !!!.
Bon courage donc.
A+
Didier
Pour ma part j'ai utilisé un bout de code nommé E_memmap.pas qui enveloppe l'api pour de Windows. Je l'ai utilisé pour faire de la communication et des échanges de données entre différents threads.
Ca marche très bien une fois que tu as compris le fonctionnement du pointeur non typé. C'est en plus très rapide comme accès partagé.
Par contre, il faut absoluement protéger les accès avec des mutex sous peine d'avoir des trucs bizarres... E_memmap contient ce code.
Si tu veux ce bout de code (qui n'est pas de moi), envoie moi un e-mail...
A+
ReBonjour,
Pour repondre à Mikaël... Je suis aussi interressé par ton bout de code
Cordialement
A quelle licence ce bout de code est-elle soumise ? Si c'est libre, je pense que tu peux poster en direct sur le forum non ?Envoyé par Anonymous
Je pourrai avoir le lien vers la page où tu as obtenu le code en question ?
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager