Commentçamarche.net
CodeS-SourceS
Rechercher un code, un tuto, une réponse

Partage mémoire entre exes via une dll [dataseg vc++]

0/5 (10 avis)

Vue 8 731 fois - Téléchargée 869 fois

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 / Exemple :


//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 !

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.