Shared Memory in DLLs

Cromon

Erfahrenes Mitglied
Hallo zusammen!

Momentan versuche eine DLL zu machen welche sozusagen als Interoperator zwischen einer Anwendung und einem "Control-Panel" zu machen. Grundsätzlich habe ich bis jetzt folgenden Ansatz verwendet:
Ich habe eine Funktion, deren Adresse ich nach jedem Build exportiere. Diese starte ich via CreateRemoteThread und der Rückgabewert ist die Adresse eines Arrays mit Adressen von Funktionen zum "kooperieren" zwischen den beiden Anwendungen. Funktioniert soweit gut, ist aber einerseits umständlich, andererseits sehen einige Antivirenprogramme mein Control-Panel heuristisch als schädlich an (halt weil es sich in einen Prozess "einschleust"). Nun habe ich gelesen, dass es die Möglichkeit gibt gewisse Variabeln in einer DLL in einen geteilten Bereich, der systemweit geteilt wird zu schreiben. Aber ich habe gelesen, dass das nur für POD-Typen geht. Also dass es da nur über Umwege geht Klassen zu teilen.

Gut, kurz gesagt:
Ich möchte den Zeiger auf eine Instanz einer Klasse "teilen" die Funktionalitäten bietet zur gegenseitigen Interoperabilität. Wie kann ich sowas denn leicht machen? Einfach so einen Zeiger in den geteilten Bereich zu schreiben geht ja so viel ich gelesen habe nicht. Was gibt es für Alternativen?

Gruss
Cromon
 
Ok, meine weiteren Recherchen haben mir gezeigt, dass ich da mit MapFiles auch ganze Speicherblöcke verteilen kann. Bevor ich meine eigentliche Frage stelle und hier reineditiere werde ich zuerst mal testen, ob es nicht vielleicht sogar schon so geht, wie ich mir das vorstelle ;)
 
Mit was arbeitest du denn?
Mit Microsoft Visual Studio?
Wenn ja, dann könntest du einzelne Variablen in den Shared Memory Bereich der DLL laden

Code:
#pragma data_seg("Shared")

int MyVal = 0;

#pragma comment(linker, "/section:Shared, RWS")
#pragma data_seg()
 
Ja, das ist mir klar, allerdings kannst du damit nicht Klassen einfach so teilen. Daher habe ich vorerst mal es versucht mit MapFiles:
Code:
static LPVOID lpvMem;
static HANDLE hMapObj;

BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID)
{
	switch(fdwReason)
	{
	case DLL_PROCESS_ATTACH:
		{
			hMapObj = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(Shared), TEXT("shareClassMapping"));
			if(hMapObj == NULL)
				return FALSE;

			BOOL init = GetLastError() == ERROR_ALREADY_EXISTS ? 0 : 1;
			lpvMem = MapViewOfFile(hMapObj, FILE_MAP_WRITE, 0, 0, sizeof(Shared));
			if(lpvMem == NULL)
				return FALSE;

			if(init)
			{
				Shared* cls = new (lpvMem) Shared;
				cls->callback = NULL;
			}

			break;
		}

	case DLL_PROCESS_DETACH:
		{
			UnmapViewOfFile(lpvMem);
			CloseHandle(hMapObj);
			break;
		}
	}

	return TRUE;
}

Das funktioniert soweit auch gut. Ausserdem habe ich folgende Funktionen exportiert:
Code:
void Shared::SetCallback(Callback pFunc)
{
	callback = pFunc;
}

void Shared::CallCallback()
{
	if(callback != NULL)
		callback("Der Test!");
}

extern "C" __declspec(dllexport) Shared* GetClsPtr()
{
	return (Shared*)lpvMem;
}

Erwartungsgemäss funktioniert SetCallback einwandfrei, CallCallback natürlich nicht, da der Addressraum der Funktion ja nicht mit dem Addressraum des aufrufenden Prozesses übereinstimmt. Wie ich das am besten umgehe weiss ich noch nicht.
 
Zurück