it-swarm.com.de

Freigabe einer globalen/statischen Variablen zwischen einem Prozess und DLL

Ich möchte eine statische/globale Variable nur zwischen einem Prozess und einer DLL teilen, die vom Prozess aufgerufen wird. Exe und DLL befinden sich im selben Speicheradressraum. Ich möchte nicht, dass die Variable von anderen Prozessen gemeinsam genutzt wird.


Ausarbeitung des Problems:

Angenommen, es gibt eine statische/globale Variable x in a.cpp. Sowohl der exe foo.exe als auch die dll bar.dll haben a.cpp, daher ist die Variable x in beiden Bildern.

Jetzt lädt foo.exe dynamisch (oder statisch) bar.dll. Das Problem ist dann, ob die Variable x von Exe und DLL gemeinsam genutzt wird oder nicht.

In Windows teilen diese beiden Typen never die x: Exe und DLL haben eine separate Kopie von x. In Linux teilen sich Exe und DLL jedoch die Variable x

Leider möchte ich das Verhalten von Linux. Ich habe zuerst überlegt, pragma data_seg unter Windows zu verwenden. Selbst wenn ich das gemeinsame Datensegment richtig eingerichtet habe, teilen foo.exe und bar.dll niemals die x. Es sei daran erinnert, dass bar.dll in den Adressraum von foo.exe geladen wird. Wenn ich jedoch eine andere Instanz von foo.exe starte, wird x freigegeben. Ich möchte jedoch nicht, dass x von verschiedenen Prozessen geteilt wird. Die Verwendung von data_seg war fehlgeschlagen.

Ich kann eine speicherzugeordnete Datei verwenden, indem ich einen eindeutigen Namen zwischen exe und dll mache, den ich jetzt versuche.


Zwei Fragen:

  1. Warum ist das Verhalten von Linux und Windows unterschiedlich? Kann jemand mehr darüber erklären?
  2. Was wäre der einfachste Weg, um dieses Problem unter Windows zu lösen?
21
minjang

Zunächst fand ich, dass dieser Artikel eine sehr interessante und prägnante Lektüre über Dynamic Link-Bibliotheken war (der Artikel ist nur Linux-spezifisch, aber die Konzepte gelten sicherlich auch für Windows und Sie erhalten vielleicht einen Einblick in die anderes Verhalten, das Sie sehen). Besonders der grundlegende Unterschied zwischen statischer und dynamischer Belastung.

Ich denke, was Sie wollen oder zu implementieren versuchen, ist ein "Cross-Modul-Singleton" -Muster. Wenn Sie die Antworten zu diesem Thread lesen, weiß ich nicht, wie ich Ihre Frage besser beantworten könnte, als Ben Voigt diesen Beitrag beantwortet hat. Ich habe zuvor (einige Male tatsächlich) ein modulübergreifendes Singleton mit der von ihm beschriebenen Methode implementiert, und es funktioniert wie ein Zauber.

Natürlich können Sie nicht die Reinheit behalten, nur die globale Variable dort in der cpp-Datei zu haben. Sie müssen einen statischen Zeiger und einige Zugriffsfunktionen und Referenzzähler verwenden. Aber es kann funktionieren. Ich bin nicht so sicher, wie es möglich sein könnte, zu vermeiden, dass foo.exe und foo.exe dieselbe Instanz von globalen Daten einer bar.dll verwenden. Ich musste das nie tun und kann mir nicht wirklich einen Weg vorstellen es tut mir leid.

8
Mikael Persson

Um das Verhalten von Linux zu ermitteln, bei dem sowohl das Hauptprogramm als auch eine DLL dieselbe x verwenden, können Sie diese Variable entweder aus der DLL oder aus dem Hauptprogramm exportieren. Das andere Modul muss diese Variable importieren.

Dazu verwenden Sie DEF-Dateien ( siehe Microsoft-Dokumentation ) oder indem Sie die Verwendung mit der Variablen mit __declspec(dllexport) markieren, wo sie definiert ist, und __declspec(dllimport) in einem anderen verwendeten Modul ( siehe Microsoft-Dokumentation ). Dies ist das Gleiche wie eine Funktion, ein Objekt oder eine Variable von Modulen in Fenstern gemeinsam genutzt wird.

Wenn Sie möchten, dass ein Programm zur Laufzeit eine Bibliothek lädt, das Hauptprogramm jedoch möglicherweise die Variable verwendet, bevor die Bibliothek geladen wird, sollte das Programm die Variable exportieren und die DLL sollte sie importieren. Hier gibt es ein kleines Problem von Chicken und Egg, da die DLL vom Hauptprogramm und das Hauptprogramm von der DLL abhängt. Siehe http://www.lurklurk.org/linkers/linkers.html#wincircular

Ich habe ein Beispiel dafür geschrieben, wie Sie dies sowohl mit dem Microsoft-Compiler als auch mit mingw (gcc in Windows) tun können, einschließlich aller möglichen Verknüpfungen zwischen einem Programm und einer Bibliothek (statisch, beim Programmstart geladene DLL, geladene DLL) zur Laufzeit)

main.h

#ifndef MAIN_H
#define MAIN_H

// something that includes this
// would #include "linkage_importing.h"
// or #include "linkage_exporting.h"
// as appropriate

#ifndef EXPLICIT_MAIN
LINKAGE int x;
#endif // EXPLICIT_MAIN

#endif // MAIN_H

haupt c

#ifdef EXPLICIT_DLL
#include "dyn_link.h"
#endif // EXPLICIT_DLL
#include <stdio.h>
#include "linkage_exporting.h"
#include "main.h"
#include "linkage_importing.h"
#include "dll.h"

FNCALL_DLL get_call_dll(void);

int main(int argc, char* argv[])
{
   FNCALL_DLL fncall_dll;
   fncall_dll = get_call_dll();
   if (fncall_dll)
   {
      x = 42;
      printf("Address of x as seen from main() in main.c: %p\n", &x);
      printf("x is set to %i in main()\n", x);
      fncall_dll();
      // could also be called as (*fncall_dll)();
      // if you want to be explicit that fncall_dll is a function pointer
      printf("Value of x as seen from main() after call to call_dll(): %i\n", x);
   }
   return 0;
}

FNCALL_DLL get_call_dll(void)
{
#ifdef EXPLICIT_DLL
   return get_ptr("dll.dll", "call_dll");
#else
   return call_dll;
#endif // EXPLICIT_DLL
}

dll.h

#ifndef DLL_H
#define DLL_H

// something that includes this
// would #include "linkage_importing.h"
// or #include "linkage_exporting.h"
// as appropriate

// declaration of type to hold a
// pointer to the function
typedef void(*FNCALL_DLL)(void);

#ifndef EXPLICIT_DLL
LINKAGE void call_dll(void);
#endif // EXPLICIT_DLL

#endif // DLL_H

dll.c

#ifdef EXPLICIT_MAIN
#include "dyn_link.h"
#endif // EXPLICIT_MAIN
#include <stdio.h>
#include "linkage_importing.h"
#include "main.h"
#include "linkage_exporting.h"
#include "dll.h"

int* get_x_ptr(void);

LINKAGE void call_dll(void)
{
   int* x_ptr;
   x_ptr = get_x_ptr();
   if (x_ptr)
   {
      printf("Address of x as seen from call_dll() in dll.c: %p\n", x_ptr);
      printf("Value of x as seen in call_dll: %i()\n", *x_ptr);
      *x_ptr = 31415;
      printf("x is set to %i in call_dll()\n", *x_ptr);
   }
}

int* get_x_ptr(void)
{
#ifdef EXPLICIT_MAIN
   return get_ptr("main.exe", "x");   // see note in dyn_link.c about using the main program as a library
#else
   return &x;
#endif //EXPLICIT_MAIN
}

dyn_link.h

#ifndef DYN_LINK_H
#define DYN_LINK_H

// even though this function is used by both, we link it
// into both main.exe and dll.dll as necessary.
// It's not shared in a dll, because it helps us load dlls :)
void* get_ptr(const char* library, const char* object);

#endif // DYN_LINK_H

dyn_link.c

#include "dyn_link.h"
#include <windows.h>
#include <stdio.h>

void* get_ptr(const char* library, const char* object)
{
   HINSTANCE hdll;
   FARPROC ptr;
   hdll = 0;
   ptr = 0;

   hdll = LoadLibrary(library);
   // in a better dynamic linking library, there would be a
   // function that would call FreeLibrary(hdll) to cleanup
   //
   // in the case where you want to load an object in the main
   // program, you can use
   // hdll = GetModuleHandle(NULL);
   // because there's no need to call LoadLibrary on the
   // executable if you can get its handle by some other means.

   if (hdll)
   {
      printf("Loaded library %s\n", library);
      ptr = GetProcAddress(hdll, object);
      if (ptr)
      {
         printf("Found %s in %s\n", object, library);
      } else {
         printf("Could not find %s in %s\n", object, library);
      }
   } else {
      printf("Could not load library %s\n", library);
   }
   return ptr;
}

linkage_importing.h

// sets up some macros to handle when to use "__declspec(dllexport)",
// "__declspec(dllimport)", "extern", or nothing.

// when using the LINKAGE macro (or including a header that does):
//    use "#include <linkage_importing.h>" to make the LINKAGE macro
//    do the right thing for importing (when using functions,
//    variables, etc...)
//
//    use "#include <linkage_exporting.h>" to make the LINKAGE macro
//    do the right thing for exporting (when declaring functions,
//    variables, etc).
//
//    You can include either file at any time to change the meaning of
//    LINKAGE.

// if you declare NO_DLL these macros do not use __declspec(...), only
// "extern" as appropriate

#ifdef LINKAGE
#undef LINKAGE
#endif
#ifdef NO_DLL
   #define LINKAGE extern
#else
   #define LINKAGE extern __declspec(dllimport)
#endif

linkage_exporting.h

// See linkage_importing.h to learn how this is used
#ifdef LINKAGE
#undef LINKAGE
#endif
#ifdef NO_DLL
   #define LINKAGE
#else
   #define LINKAGE __declspec(dllexport)
#endif

build mingw explizite both.sh

#! /bin/bash
echo Building configuration where both main
echo and dll link explicitly to each other
rm -rf mingw_explicit_both
mkdir -p mingw_explicit_both/obj
cd mingw_explicit_both/obj

# compile the source code (dll created with position independent code)
gcc -c -fPIC -DEXPLICIT_MAIN ../../dll.c
gcc -c -DEXPLICIT_DLL ../../main.c
gcc -c ../../dyn_link.c

#create the dll from its object code the normal way
gcc -shared -odll.dll dll.o dyn_link.o -Wl,--out-implib,libdll.a

# create the executable
gcc -o main.exe main.o dyn_link.o

mv dll.dll ..
mv main.exe ..
cd ..

build Mingw explizite dll.sh

#! /bin/bash
echo Building configuration where main explicitly
echo links to dll, but dll implicitly links to main
rm -rf mingw_explicit_dll
mkdir -p mingw_explicit_dll/obj
cd mingw_explicit_dll/obj

# compile the source code (dll created with position independent code)
gcc -c -fPIC ../../dll.c
gcc -c -DEXPLICIT_DLL ../../main.c
gcc -c ../../dyn_link.c

# normally when linking a dll, you just use gcc
# to create the dll and its linking library (--out-implib...)
# But, this dll needs to import from main, and main's linking library doesn't exist yet
# so we create the linking library for main.o
# make sure that linking library knows to look for symbols in main.exe (the default would be a.out)
gcc -omain.exe -shared main.o -Wl,--out-implib,main.a  #note this reports failure, but it's only a failure to create main.exe, not a failure to create main.a

#create the dll from its object code the normal way (dll needs to know about main's exports)
gcc -shared -odll.dll dll.o dyn_link.o main.a -Wl,--out-implib,libdll.a

# create the executable
gcc -o main.exe main.o dyn_link.o

mv dll.dll ..
mv main.exe ..
cd ..

build mingw explizite main.sh

#! /bin/bash
echo Building configuration where dll explicitly
echo links to main, but main implicitly links to dll
rm -rf mingw_explicit_main
mkdir -p mingw_explicit_main/obj
cd mingw_explicit_main/obj

# compile the source code (dll created with position independent code)
gcc -c -fPIC -DEXPLICIT_MAIN ../../dll.c
gcc -c ../../main.c
gcc -c ../../dyn_link.c

# since the dll will link dynamically and explicitly with main, there is no need
# to create a linking library for main, and the dll can be built the regular way
gcc -shared -odll.dll dll.o dyn_link.o -Wl,--out-implib,libdll.a

# create the executable (main still links with dll implicitly)
gcc -o main.exe main.o -L. -ldll

mv dll.dll ..
mv main.exe ..
cd ..

build mingw implicit.sh

#! /bin/bash
echo Building configuration where main and
echo dll implicitly link to each other
rm -rf mingw_implicit
mkdir -p mingw_implicit/obj
cd mingw_implicit/obj

# compile the source code (dll created with position independent code)
gcc -c -fPIC ../../dll.c
gcc -c ../../main.c

# normally when linking a dll, you just use gcc
# to create the dll and its linking library (--out-implib...)
# But, this dll needs to import from main, and main's linking library doesn't exist yet
# so we create the linking library for main.o
# make sure that linking library knows to look for symbols in main.exe (the default would be a.out)
gcc -omain.exe -shared main.o -Wl,--out-implib,main.a  #note this reports failure, but it's only a failure to create main.exe, not a failure to create main.a

# create the dll from its object code the normal way (dll needs to know about main's exports)
gcc -shared -odll.dll dll.o main.a -Wl,--out-implib,libdll.a

# create the executable (exe needs to know about dll's exports)
gcc -o main.exe main.o -L. -ldll

mv dll.dll ..
mv main.exe ..
cd ..

mingw static.sh erstellen

#! /bin/bash
echo Building configuration where main and dll
echo statically link to each other
rm -rf mingw_static
mkdir -p mingw_static/obj
cd mingw_static/obj

# compile the source code
gcc -c -DNO_DLL ../../dll.c
gcc -c -DNO_DLL ../../main.c

# create the static library
ar -rcs dll.a dll.o

# link the executable
gcc -o main.exe main.o dll.a

mv main.exe ../
cd ..

erstelle msvc explizit both.bat

@echo off
echo Building configuration where both main
echo and dll link explicitly to each other
rd /s /q win_explicit_both
md win_explicit_both\obj
cd win_explicit_both\obj

rem compile the source code
cl /nologo /c /DEXPLICIT_MAIN ..\..\dll.c
cl /nologo /c /DEXPLICIT_DLL ..\..\main.c
cl /nologo /c ..\..\dyn_link.c

rem create the dll from its object code the normal way
link /nologo /dll dll.obj dyn_link.obj

rem create the executable
link /nologo main.obj dyn_link.obj

move dll.dll ..\
move main.exe ..\
cd ..

erstelle msvc explizite dll.bat

@echo off
echo Building configuration where main explicitly
echo links to dll, but dll implicitly links to main
rd /s /q win_explicit_dll
md win_explicit_dll\obj
cd win_explicit_dll\obj

rem compile the source code
cl /nologo /c ..\..\dll.c
cl /nologo /c /DEXPLICIT_DLL ..\..\main.c
cl /nologo /c ..\..\dyn_link.c

rem normally when linking a dll, you just use the link command
rem that creates the dll and its linking library.
rem But, this dll needs to import from main, and main's linking library doesn't exist yet
rem so we create the linking library for main.obj
rem make sure that linking library knows to look for symbols in main.exe (the default would be main.dll)
lib /nologo /def /name:main.exe main.obj

rem create the dll from its object code the normal way (dll needs to know about main's exports)
link /nologo /dll dll.obj main.lib

rem create the executable
link /nologo main.obj dyn_link.obj

move dll.dll ..\
move main.exe ..\
cd ..

erstelle msvc explizit main.bat

@echo off
echo Building configuration where dll explicitly
echo links to main, but main implicitly links to dll
rd /s /q win_explicit_main
md win_explicit_main\obj
cd win_explicit_main\obj

rem compile the source code
cl /nologo /c /DEXPLICIT_MAIN ..\..\dll.c
cl /nologo /c ..\..\main.c
cl /nologo /c ..\..\dyn_link.c

rem since the dll will link dynamically and explicitly with main, there is no need
rem to create a linking library for main, and the dll can be built the regular way
link /nologo /dll dll.obj dyn_link.obj

rem create the executable (main still links with dll implicitly)
link /nologo main.obj dll.lib

move dll.dll ..\
move main.exe ..\
cd ..

erstellen Sie msvc implicit.bat

@echo off
echo Building configuration where main and
echo dll implicitly link to each other
rd /s /q win_implicit
md win_implicit\obj
cd win_implicit\obj

rem compile the source code
cl /nologo /c ..\..\dll.c
cl /nologo /c ..\..\main.c

rem normally when linking a dll, you just use the link command
rem that creates the dll and its linking library.
rem But, this dll needs to import from main, and main's linking library doesn't exist yet
rem so we create the linking library for main.obj
rem make sure that linking library knows to look for symbols in main.exe (the default would be main.dll)
lib /nologo /def /name:main.exe main.obj

rem create the dll from its object code the normal way (dll needs to know about main's exports)
link /nologo /dll dll.obj main.lib

rem create the executable (exe needs to know about dll's exports)
link /nologo main.obj dll.lib

move dll.dll ..\
move main.exe ..\
cd ..

msvc static.bat erstellen

@echo off
echo Building configuration where main and dll
echo statically link to each other
rd /s /q win_static
md win_static\obj
cd win_static\obj

rem compile the source code
cl /nologo /DNO_DLL /c ..\..\dll.c
cl /nologo /DNO_DLL /c ..\..\main.c

rem create the static library
lib /nologo dll.obj

rem link the executable
link /nologo main.obj dll.lib

move main.exe ..\
cd ..
11
James Caccese

Wenn foo.exe immer bar.dll lädt, können Sie die Variable in bar.dll implementieren und exportieren. Beispielsweise wurde einige Datei b.cpp nur in bar.dll und nicht in foo.exe kompiliert:

__declspec(dllexport) int x;

Dann importieren Sie es in eine Quelldatei c.cpp, die in foo.exe kompiliert ist:

__declspec(dllimport) int x;

Wenn jedoch foo.exe manchmal die Datei bar.dll nicht lädt, funktioniert dies nicht. Außerdem schreibe ich dies aus dem Gedächtnis und es könnte ein paar syntaktische Fehler geben, aber hoffentlich reicht es, um Sie in die richtige Richtung zu weisen.

Ich kann nicht beantworten, warum Linux anders ist.

5
Ciaran Keating

Ich fand, dass dies eine so interessante Frage war, dass ich mir die Zeit nahm, ein umfangreiches Tutorial zu schreiben, wie DLLs verwendet werden können, um Daten zwischen mehreren DLLs auszutauschen (entweder implizit oder explizit verknüpft), aber auch sicherstellen, dass die Daten nicht zwischen separaten Prozessen gemeinsam genutzt werden der gleichen ausführbaren Datei.

Den vollständigen Artikel finden Sie hier: http://3dgep.com/?p=1759


Eine Lösung für dieses Problem, die meiner Meinung nach gut funktioniert, besteht darin, eine "gemeinsame" oder "gemeinsam genutzte" DLL zu erstellen, die alle Daten und Methoden definiert, die Sie über mehrere DLLs (aber nicht zwischen Prozessen) gemeinsam nutzen möchten.

Angenommen, Sie möchten eine Singleton-Klasse definieren, auf die über den Hauptanwendungscode (die EXE-Datei) zugegriffen werden kann. Sie möchten jedoch auch auf die Singleton-Instanz in shared (entweder implizit oder explizit verknüpfte DLL) zugreifen. Zuerst müssten Sie die Singleton-Klasse in der "allgemeinen" DLL deklarieren:

// Export the class when compiling the DLL, 
// otherwise import the class when using the DLL.
class __declspec(dllexport) MySingleton 
{
public:
    static MySingleton& Instance();
};

Beim Kompilieren des CommonDLL-Projekts müssen Sie die Klassendeklaration exportieren, indem Sie die Klasse mit __declspec(dllexport) dekorieren. Wenn Sie die DLL verwenden (z. B. in der Anwendung), muss die Klassendefinition mit importiert werden die Klasse mit __declspec(dllimport) dekorieren.

Wenn Sie eine Klasse exportieren, indem Sie die Klasse mit dem __declspec(dllexport)-Bezeichner dekorieren, werden alle Methoden und Daten der Klasse (auch private Daten) aus der DLL exportiert und können von jeder DLL oder EXE-Datei verwendet werden impliziert eine Verknüpfung zu der allgemeinen DLL.

Die Definition der MySingleton-Klasse könnte in etwa wie folgt aussehen:

MySingleton& MySingleton::Instance()
{
    static MySingleton instance;
    return instance;
}

Beim Kompilieren der allgemeinen DLL werden zwei Dateien erzeugt:

  1. Die Datei Common.DLL. Dies ist die gemeinsam genutzte Bibliothek, die die von der DLL verwendeten Mehthods und Daten definiert.
  2. Die Datei Common.LIB, die Stubs für die aus der DLL exportierten Methoden und Member deklariert.

Wenn Sie Ihre Anwendung mit der exportierten LIB-Datei verknüpfen, wird die Datei DLL zur Laufzeit implizit verknüpft (sofern sich die Datei DLL in den Suchpfaden DLL) befindet, und Sie hat Zugriff auf das in der Datei CommonDLL.DLL definierte Singleton.

Außerdem hat jede gemeinsam genutzte Bibliothek (z. B. Plug-Ins), die eine Verknüpfung zur CommonDLL.LIB-Datei herstellt, Zugriff auf dieselben Singleton-Instanzen, wenn sie von der Anwendung dynamisch geladen wird.

Eine vollständige Erläuterung dieser Lösung einschließlich eines Quellcode-Beispiels finden Sie im folgenden Artikel, den ich mit dem Titel "Verwenden von Dynamic Link Libraries (DLL) zum Erstellen von Plug-Ins" gepostet hat:

http://3dgep.com/?p=1759

4
Jeremiah

Der Unterschied zwischen GCC und Visual Studio besteht darin, dass unter Linux der Code implizit das Anzeigen von Symbolen aus anderen, dynamisch verknüpften (gemeinsam genutzten) Bibliotheken zulässt, ohne dass Sie als Programmierer etwas Besonderes tun müssen. Alle Symbole stehen in der gemeinsam genutzten (dynamisch verknüpften) Bibliothek zur Verfügung, damit der dynamische Linker bei Ausführung des Programms aufgelöst werden kann. Unter Windows müssen Sie das Symbol spezifisch aus der DLL exportieren und auch explizit in das Programm oder die Bibliothek importieren, in der es verwendet wird. (Normalerweise erfolgt dies über ein Makro (#define), das beim Erstellen der DLL selbst die Deklaration dllexport in einer Headerdatei enthält. Wenn die Headerdatei jedoch von einem anderen Programm mit der DLL eingeschlossen wird, wird sie um den DLLimport erweitert Stattdessen eine Erklärung: Meiner Meinung nach ist dies ein Schmerz im Nacken, und das Verhalten von GCC ist einfacher, da Sie nichts Besonderes tun müssen, um das Verhalten zu erhalten, das Sie normalerweise möchten.

In einer neueren Version von GCC können Sie den Standard festlegen, um Symbole beim Erstellen einer dynamischen (gemeinsam genutzten) Bibliothek auszublenden, wenn Sie möchten.

3
Reed Hedges

Vielen Dank für die Bereitstellung verschiedener Lösungen. Ich habe mir diese Option angesehen und beschlossen, das Cross-Modul-Singleton mithilfe des Shared Memory zu implementieren, und es hat auch für mich gut funktioniert .

1
Zeeshan

Wenn ich Ihre Frage richtig verstehe, verknüpfen Sie a.cpp statisch mit foo.exe und bar.dll, sodass Sie 2 Instanzen von x erhalten.

Wenn Sie eine dritte DLL erstellt haben (sagen Sie "a.dll") und "foo.exe" und "bar.dll" dynamisch mit "a.dll" verknüpfen, erhalten Sie das gewünschte Verhalten:

  1. foo.exe lädt a.dll und erstellt x.
  2. bar.dll wird geladen und sieht, dass a.dll geladen wird und es nicht erneut lädt, sie teilen sich x.
  3. Ein anderer Prozess lädt a.dll, es bekommt sein eigenes x.
0
zdan

Ich habe viele Antworten auf diese Frage gesehen und da es etwas knifflig und unklar ist, möchte ich das folgende Szenario vorstellen. Wir möchten eine globale Variable zwischen einer DLL und einem Hauptprogramm teilen und auch den Zugriff auf diese Variable von verschiedenen Modulen in der DLL und im Hauptprogramm erlauben.

Die Variable ist ein BOOL, das angibt, ob das Programm weiter ausgeführt oder gestoppt werden soll. Der Variablenname lautet ShouldRun ;

Im Hauptprogramm müssen wir setzen:

__declspec(dllexport)  bool ShouldRun;

Im Hauptmodul der DLL müssen wir Folgendes einfügen:

extern "C" BOOL __declspec(dllexport) ShouldRun = TRUE;

In jedem anderen Modul innerhalb des Projekts DLL werden wir Folgendes verwenden:

extern  "C" BOOL ShouldRun;
0