2017-10-26 2 views
2

Ich bin auf der Suche nach einem sauberen Weg, Bibliothek explizit zu laden. Meistens habe ich ein LIB und ein DLL-Paar, so dass die LIB alle "Lade-Sachen" verarbeiten und ich die Funktion in der DLL direkt aufrufen kann. Wenn dies explizit tun, muss ich irgendwie die folgenden Funktionen ausführen:saubere Möglichkeit, Bibliothek explizit zu laden

HMODULE libA = LoadLibrary("dllA.dll"); // NULL if load failed 
HMODULE libB = LoadLibrary("dllB.dll"); // NULL if load failed 

void (*functionA)(void) = libA ? GetProcAddress(libA,"functionA"):NULL; 
void (*functionB)(void) = libB ? GetProcAddress(libB,"functionB"):NULL; 

Es chaotisch sein wird, wenn die Loadlibrary() und GetProcAddress() sind alle über meinen Code gefunden, wenn ich Funktion in DLL aufrufen müssen. Ich würde gerne wissen, ob es einen sauberen Weg gibt, so dass ich die gesamte Handhabung in 1-2 Dateien schreiben und die Funktionen aufrufen kann, als ob ich die Bibliothek implizit über LIB und DLL-Paar lade.

+2

Sie können einmal an einer Stelle "LoadLibrary" und dann mehrmals "GetProcAddress" aufrufen, um alle Funktionszeiger zu erhalten und sie dann zu verwenden. Sie können auch Verzögerung laden für diese DLL implementieren – RbMm

+2

Dies ist Programmierung 101. Erstellen Sie eine Funktion oder eine Klasse, die diese Funktionalität für Sie umschließt und schützt Sie vor den Details. –

+0

Sie können sich auch [Boost.DLL] (http://www.boost.org/doc/libs/release/doc/html/boost_dll.html) ansehen, die etwas Abstraktion bietet. Habe es selbst noch nicht benutzt, aber die [Beispiele] (http://www.boost.org/doc/libs/release/doc/html/boost_dll/tutorial.html#boost_dll.tutorial.plugin_basics) sehen ziemlich sauber aus. – zett42

Antwort

2

In der Tat gibt es einen Weg, um alle implizite Verknüpfung Bequemlichkeit zu erhalten, während immer noch in der Lage, sowohl Bibliotheken laden als auch Symbol Lookup fehlschlagen. Visual Studio bietet Linker Support for Delay-Loaded DLLs, die dem Benutzercode die Möglichkeit geben, sich in den Loader einzuklinken und beliebige Wiederherstellungsstrategien für nicht verfügbare Symbole zu implementieren (z. B. durch Zurückgeben eines Nicht-Op-Stubs). Dies ermöglicht es, alle Fehlerbehandlungen an einem einzigen Ort zu konsolidieren.

+0

Ich verwende derzeit auch die Verzögerungslast. Mein Ziel ist eine plattformunabhängige Option. Ich weiß, dass die Ladebibliothek und GetProcAddress auch plattformabhängig sind, also brauche ich ein separates Modul, um all diese "Lade-Sachen" zu handhaben, so dass das Modul in Zukunft leicht modifiziert werden kann. –

+2

@RonaldKu: Das Laden von Modulen ist plattformabhängig. Sie können jedoch eine plattformunabhängige Schnittstelle bereitstellen, z. indem Sie 'nullptr's für nicht verfügbare Symbole zurückgeben. Oder 'std :: optional's und die Verwendung von [value_or] (http://en.cppreference.com/w/cpp/utility/optional/value_or) mit einem stopplosen Zeiger. Ich werde sehen, ob ich einen Beispielcode erfinden kann, um das Konzept zu veranschaulichen, wenn die Zeit es erlaubt. – IInspectable

0

Schreiben Sie eine reine Schnittstelle zu den externen Funktionen, die Sie benötigen. (Plattformabhängig)

Stellen Sie eine Implementierungsklasse (für Ihre Plattform) bereit. Laden Sie für Ihre Windows-Implementierung die DLL, erhalten Sie zunächst die Prozeduradresse.

Wenn die Schnittstellenfunktion aufgerufen werden muss, leitet die Klasse den Aufruf an die geladene DLL weiter.

Verwenden Sie einen ähnlichen Weg für andere Plattformen.

Dies ist nichts anderes als die Verwendung von verzögerungsgeladenen DLLs. Es ist nur eine manuelle Lösung. Aber der Ansatz der Verwendung einer Schnittstelle ermöglicht Ihnen eine echte plattformabhängige Lösung.

Verwandte Themen