begin process at 2008 07 06 16:19:49
1 205 627 membres
195 nouveaux aujourd'hui
14 119 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

PARTAGE MÉMOIRE ENTRE EXES VIA UNE DLL [DATASEG VC++]


Information sur la source

Catégorie :Astuces Niveau : Initié Date de création : 25/02/2003 Date de mise à jour : 25/02/2003 19:40:07 Vu / téléchargé: 5 015 / 776

Note :
7 / 10 - par 4 personnes
7,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (9)
Ajouter un commentaire et/ou une note

Description

Parfois, il faut pouvoir faire communiquer deux exécutables qui vivent chacun dans un espace mémoire séparé. Une petite DLL peut les réconcilier.
Cette DLL n'est pas loin d'être la plus petite du monde, elle ne contient en fait que la zone de partage ( aucune ressource, aucune fonction... enfin au niveau du code source car le compilateur génère tout de même DllMain)

il y a la DLL (minDLL.H/.cpp) et le fichier de définition IMPORTANT car il comporte le déclaration de la zone (du segment mémoire) de partage
il y a le programme main (test.cpp)

le partage se limite à un entier et une chaine de caractère fixe
Pour tester, lancer deux instance du prog, modifier dans le prog1 les données et vérifier avec le prog2 la communication...  

Source

  • //minDLL.H
  • #include <windows.h>
  • // Définition d'une variable globale int glob
  • // DLLBUILD est notre choix de symbole pour indiquer le sens d'utilisation de la variable
  • //ceci est fait pour pouvoir utiliser le même .H dans les clients et dans la DLL
  • //et éviter le warning produit lorsque dllexport et dllimport coexistent (minDLLcpp et minDLLh)
  • #ifndef DLLBUILD
  • #define DLLEXT __declspec(dllimport)
  • #else
  • #define DLLEXT __declspec(dllexport)
  • #endif
  • extern DLLEXT int glob;
  • const int MAXCAR=5;
  • extern DLLEXT char gString[MAXCAR];
  • //minDLL.cpp
  • #include "mindll.h"
  • //la clause pragma suivante sert à partager la mémoire entre plusieurs process
  • //elle va de pair avec la section du .DEF ... nommée partage
  • #pragma data_seg("partage")
  • DLLEXT int glob = 1 ; //Valeur d'initialisation
  • DLLEXT char gString[MAXCAR]="abcd";
  • #pragma data_seg()
  • //minDLL.def
  • LIBRARY minDLL
  • DESCRIPTION 'petite DLL de partage'
  • EXPORTS glob ;DATA
  • gString
  • SECTIONS
  • partage READ WRITE SHARED
  • //Test.cpp
  • #include <iostream>
  • #include "..\minDLL.h"
  • using namespace std;
  • int main(int argc, char* argv[])
  • {
  • using std::cin; using std::cout; using std::endl;
  • int i;
  • char buffer[80];
  • cout << "utilisation statique de la DLL" << endl;
  • cout << "ancienne valeur globale = " << glob << endl;
  • cout << "ancienne valeur chaine globale = " << gString << endl;
  • while (true)
  • {
  • cout << "entrer une nouvelle valeur globale entiere \n"
  • "suivie d'une nouvelle valeur globale char[" << MAXCAR <<"] (0 pour terminer)\n";
  • if (!(cin >> i)) //protéger le "cin"
  • { cout << "un entier SVP!\n"; cin.clear(); cin.getline(buffer,80); continue;}
  • if (!i) return 0;
  • cout << "ancienne valeur globale = " << glob << endl;
  • glob=i;
  • cout << "nouvelle valeur globale = " << glob << endl<< endl;
  • cin.getline(buffer, 80);
  • cout << "ancienne valeur chaine globale = " << gString << endl;
  • strncpy(gString, buffer, MAXCAR); //protection contre débordement sur variable partagée
  • cout << "nouvelle valeur chaine globale = " << gString << endl;
  • }
  • return 0;
  • }
//minDLL.H
#include <windows.h>
// Définition d'une variable globale int glob
// DLLBUILD est notre choix de symbole pour indiquer le sens d'utilisation de la variable 
//ceci est fait pour pouvoir utiliser le même .H dans les clients et dans la DLL 
//et éviter le warning produit lorsque dllexport et dllimport coexistent (minDLLcpp et minDLLh) 

#ifndef DLLBUILD 
#define	DLLEXT __declspec(dllimport) 
#else 
#define	DLLEXT __declspec(dllexport) 
#endif 

extern DLLEXT int glob;
const int MAXCAR=5;
extern DLLEXT char gString[MAXCAR];

//minDLL.cpp
#include "mindll.h" 
//la clause pragma suivante sert à partager la mémoire entre plusieurs process
//elle va de pair avec la section du .DEF ... nommée partage
#pragma data_seg("partage")  
DLLEXT int glob = 1 ; //Valeur d'initialisation 
DLLEXT char gString[MAXCAR]="abcd";
#pragma data_seg() 

//minDLL.def
LIBRARY 	minDLL 
DESCRIPTION 'petite DLL de partage'
EXPORTS 	glob ;DATA
			gString
SECTIONS 	
			partage READ WRITE SHARED

//Test.cpp
#include <iostream>
#include "..\minDLL.h"
using namespace std;


int main(int argc, char* argv[])
{
	using std::cin; using std::cout; using std::endl; 
	int i;
	char buffer[80];
	cout << "utilisation statique de la DLL" << endl;
		cout << "ancienne valeur globale  = " << glob << endl;
		cout << "ancienne valeur chaine globale  = " << gString << endl;
	while (true)
	{
		cout << "entrer une nouvelle valeur globale entiere \n"
			"suivie d'une nouvelle valeur globale char[" << MAXCAR <<"] (0 pour terminer)\n";
		
		if (!(cin >> i)) //protéger le "cin"
		{ cout << "un entier SVP!\n"; cin.clear(); cin.getline(buffer,80); continue;}

		if (!i) return 0;

		cout << "ancienne valeur globale  = " << glob << endl;
		glob=i;
		cout << "nouvelle valeur globale  = " << glob << endl<< endl;

		cin.getline(buffer, 80);
		cout << "ancienne valeur chaine globale  = " << gString << endl;
		strncpy(gString, buffer, MAXCAR); //protection contre débordement sur variable partagée
		cout << "nouvelle valeur chaine globale  = " << gString << endl;

	}
	return 0;
}
  

Conclusion

on peut bien sûr utiliser un link dynamique, selon le design pattern du "lazy loading"  
inconvénient ? pas d'avertissement que le process concurrent viens de modifier les données.
Ce n'est pas le DDE, encore moins COM !
Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

  • signaler à un administrateur
    Commentaire de BlackGoddess le 13/05/2003 20:58:49

    ké blaireau ...

    jolie cette source, félicitations si c'est toi qui l'a faite, et si ce n'est pas toi, merci de l'avoir remise ici :)

  • signaler à un administrateur
    Commentaire de Bub325 le 10/06/2003 00:36:50

    personnellement je trouve kil est bcp plus simple d'utiliser les fichier masqués et partager ainsi une zone mémoire sans avoir besoin d'utiliser de dll exterieure dédiées. Si vous avez des questions à propos des fichiers masqué demandez le moi par message et je ferais un exemple (pour windows seulement).

  • signaler à un administrateur
    Commentaire de BlackGoddess le 10/06/2003 09:33:51

    bin ... oui un exemple stp :)

  • signaler à un administrateur
    Commentaire de Bub325 le 10/06/2003 13:10:08

    ok, donc voici un article que je vient de poster qui montre l'utilisation des fichiers mappés pour le partage de variable entre application:
    http://www.cppfrance.com/article.aspx?Val=1967

    laissez m'en des nouvelles svp =)

  • signaler à un administrateur
    Commentaire de andros le 02/10/2003 16:28:54

    oui bien pratique. Ca marche aussi en chargeant la dll de façon dynamique (du moins en lecture simultanée, écriture par chaque process en différé) sans créer de mutex nommé.
    Dommage, j'ai essayé la même chose sous BC6, mais il plante à SECTIONS (dans le .DEF) en me disant que 'partage' est vide (à priori donc pas la même syntaxe que VC). Peut-être qq a l'astuce ??? (moi pas trouvé). J'ai bien VC6 mais en version commerciale avec pop-up de licence au chargement de la DLL...
    D'après vous, est-ce une méthode +rapide que le FileMapping ???

  • signaler à un administrateur
    Commentaire de mone et pock le 09/01/2004 09:40:27

    Bon...je viens de me mettre au c++, et j'essaie de comprendre le partage des segments de données...j'ai téléchargé un code sur ce sujet déjà sur le site http://www.codeproject.com et j'avais un message d'erreur du type :
    LINK : fatal error LNK1104: cannot open file "..\debug\test01.lib"
    aujourd'hui j'ai le droit à un message identique
    LINK : fatal error LNK1104: cannot open file "..\debug\minDLL.lib"
    que se passe t'il?

  • signaler à un administrateur
    Commentaire de mone et pock le 09/01/2004 10:01:11

    Après de multiples tentatives...je viens de trouver un moyen de compiler...mais ça me semble curieux! Je suis obligé de compiler chacun des fichiers cpp les uns après les autres puis enfin de compiler le projet global pour que ça fonctionne...je pense qu'il ya plus simple...mais je ne vois pas comment faire...
    merci de votre aide!

  • signaler à un administrateur
    Commentaire de vieuxLion le 09/01/2004 10:55:40

    salut "mone et pock"

    le message d'erreur de link signifie que le linkeur ne trouve pas le fichier .LIB
    vérifie simplement le répertoire dans lequel tu l'as mis (par rapport à ton projet de test)

  • signaler à un administrateur
    Commentaire de mone et pock le 09/01/2004 11:00:25

    en effet, c'était bien le premier problème!néanmoins, même lorsque tout les fichiers sont correctement placé, est il obligatoire de compiler chacun des fichiers avant de faire une compile générale??

Ajouter un commentaire

Pub



Appels d'offres

Plugin Dialer outlook
Budget : 2 000€
Travail graphique- ill...
Budget : 1 000€
creation de marque et ...
Budget : 1 000€

CalendriCode

Juillet 2008
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Boutique

Boutique de goodies CodeS-SourceS