2016-07-01 24 views
-1

Ich untersuche ein Plugin-Typ-System mit Microsoft C++. Das Problem, das ich habe, ist, ich bin nicht in der Lage, eine statische Variable in einer gemeinsam genutzten Bibliothek zwischen dem Hauptprogramm und der Plugin-Bibliothek zu teilen.Kann VC++ Statik in einer Bibliothek freigeben, wenn Laufzeitdll loading

Hauptprogramm:

#include "stdafx.h" 
#include "windows.h" 
#include "..\EngineLib\Engine.h" 

typedef void(*PluginFuncPtrType)(void); 

int main() 
{ 
    printf("Main Test.\n"); 

    HINSTANCE hRuntimeDll = LoadLibrary(L"PluginLib.dll"); 
    if (!hRuntimeDll) { 
     printf("Could not load the dynamic library.\n"); 
    } 

    PluginFuncPtrType pluginFuncPtr = (PluginFuncPtrType)GetProcAddress(hRuntimeDll, "PluginFunc"); 
    if (!pluginFuncPtr) { 
     printf("Could not load the function from dynamic library.\n"); 
    } 
    else { 
     pluginFuncPtr(); 
     printf("Main engine counter %i.\n", EngineFunc()); 
     pluginFuncPtr(); 
     printf("Main engine counter %i.\n", EngineFunc()); 
     pluginFuncPtr(); 
     printf("Main engine counter %i.\n", EngineFunc()); 
    } 

    printf("Press any key to exit..."); 
    getchar(); 
} 

Eine gemeinsame Bibliothek, die durch das Hauptprogramm (statisch gelinkt) und das Plugin dll (die auch in dieser gemeinsamen Bibliothek verknüpft statisch) verwendet wird

Shared Library Header (engine.h):

#pragma once 
#include <stdio.h> 
int EngineFunc(); 

Shared Library Umsetzung:

#include "stdafx.h" 
#include "Engine.h" 
#include <stdio.h> 

static int _engineCounter = 1; 

int EngineFunc() 
{ 
    return _engineCounter++; 
} 

Plugin DLL-Header (plugin.h):

#pragma once 

#include "stdafx.h" 
#include <stdio.h> 
#include "..\EngineLib\Engine.h" 

extern "C" __declspec(dllexport) void PluginFunc(void); 

Plugin Implementierung:

#include "Plugin.h" 

void PluginFunc(void) 
{ 
    printf("PluginFunc engine counter=%i\n", EngineFunc()); 
} 

Ausgabe von main.exe:

Main Test. 
PluginFunc engine counter=1 
Main engine counter 1. 
PluginFunc engine counter=2 
Main engine counter 2. 
PluginFunc engine counter=3 
Main engine counter 3. 
Press any key to exit... 

Main.exe statisch Links gegen EngineLib.lib. PluginLib.dll statisch Verbindungen gegen EngineLib.lib.

Main verknüpft NICHT mit PluginLib.dll, sondern lädt es zur Laufzeit.

Von was ich verstehe, wenn eine DLL zur Laufzeit geladen wird mit LoadLibrary es bekommt seinen eigenen virtuellen Speicher Adressraum und daher verschiedene statische Variablen zur gleichen Bibliothek statisch in das Hauptprogramm verknüpft. Ich glaube, dass Linux dynamisch geladene Bibliotheken den gleichen virtuellen Speicherplatz teilen.

Meine Frage ist, ob es einen Ansatz gibt, den ich für Windows verwenden kann, damit die dynamisch geladene DLL die gleichen statischen Variablen wie die statisch verknüpfte Bibliothek verwenden kann?

Antwort

0

Erstellen Sie eine DLL. "EngineStatics.dll". Definieren Sie die statische Datei in dieser DLL und exportieren Sie sie mit __declspec (dllexport).

Fügen Sie in Ihrer exe eine Abhängigkeit von der obigen DLL hinzu. Und deklariere das gleiche static mit __declspec (dllimport).

In Ihrer Plugin dll, eine Abhängigkeit von der gleichen DLL hinzufügen, und es auch mit delcspec importieren (dllimport)


Dies scheint viel einfacher als meine ursprüngliche Antwort von den statischen von der EXE-Export direkt , indem Sie die Tools in eine Export-Lib umwandeln und dann die DLL des Plugins mit der lib-Datei des EXE verknüpfen.

+0

Ich möchte nicht direkt auf die statische _engineCounter-Variable zugreifen. In meinem radikal vereinfachten Beispiel stellt die statische Variable etwas dar, das sowohl geladene Kopien von EngineLib aktualisiert als auch dass zwei verschiedene Benutzer dieser Bibliothek die Aktualisierungen des jeweils anderen sehen müssen. – sipwiz