Frage

Ich habe viele ein Tutorial / Artikel auf nicht verwalteten DLLs in C ++ gelesen. Für das Leben von mir, aber ich kann nicht scheinen, um das Konzept zu begreifen. Ich bin leicht durch die scheinbare Uneinigkeit darüber verwirrt, ob es eine Header-Datei muss, wie es exportieren, ob ich eine LIB-Datei benötigen und was Sie haben.

Also, nehmen wir an, ich habe nur eine Funktion wie folgt:

public int calculateSquare(int num)
{
    return num*num;
}

Das Ignorieren des eigentlichen Code, was benötige ich diese einfache Funktion zu machen, von selbst, in eine DLL, die dann kann ich anrufen? Muß ich nur hinzufügen, __dllexport oder was auch immer es ist, in der ersten Zeile oder benötige ich einen Header? Ich bin von all dies verwirrt.

War es hilfreich?

Lösung

ich nicht genug betonen kann, die C ++ Compiler nicht die Header-Dateien nicht sehen, nachdem der Prä-Prozessor durchgeführt wird, gibt es nur eine große Quelldatei (auch als Übersetzungseinheit). So streng brauchen Sie keinen Header diese Funktion aus einer DLL zu exportieren. Was Sie tun müssen ist eine Form von bedingten Kompilierung die Funktion in der DLL zu exportieren, die Sie kompilieren und es in der Client-Code zu importieren.

Typischerweise wird dies mit einer Kombination von Makros und Header-Dateien durchgeführt. Sie erstellen ein Makro MYIMPORTEXPORT und durch die Verwendung von Makro bedingten Anweisungen genannt Sie es wie __declspec (dllexport) in der DLL und __declspec (dllimport) im Client-Code arbeiten.

in der Datei MYIMPORTEXPORT.h

#ifdef SOME_CONDITION
#define MYIMPORTEXPORT __declspec( dllexport )
#else
#define MYIMPORTEXPORT __declspec( dllimport )
#endif

in der Datei MyHeader.h

#include <MyImportExport.h>

MYIMPORTEXPORT public int calculateSquare(int num)
{
    return num*num;
}

in dll CPP-Datei

#define SOME_CONDITION

#include <MyHeader.h>

in Client-Code CPP-Datei

#include <MyHeader.h>

Natürlich müssen Sie auch an den Linker signalisieren, dass Sie bauen eine DLL mit der Option / DLL .

Der Build-Prozess wird auch eine LIB-Datei machen, ist dies ein statischer lib - der Stummel in diesem Fall genannt -, die der Client-Code verknüpfen muss, als ob es zu einem echten statischen lib wurde verknüpfen. Automagically, wird die DLL geladen werden, wenn der Client-Code ausgeführt wird. Natürlich muss die DLL durch das Betriebssystem durch seinen Lookup-Mechanismus gefunden werden, was bedeutet, dass Sie nicht nur überall die DLL setzen können, aber an einem bestimmten Ort. Hier mehr dazu ist.

Ein sehr praktisches Tool, um zu sehen, ob Sie die korrekte Funktion aus der DLL exportierten, und ob der Client-Code korrekt importiert sind dumpbin . Führen Sie es mit / export und / IMPORT ist.

Andere Tipps

QBziZ‘Antwort ist richtig genug. Siehe Unmanaged DLLs in C ++

es Abwicklung: In C ++, wenn Sie ein Symbol verwenden müssen, müssen Sie den Compiler sagen, es existiert, und oft, dessen Prototyp

.

In anderen Sprachen wird der Compiler erkundet gerade die Bibliothek auf seinem eigenen, und das Symbol finden, et voilà .

In C ++ müssen Sie den Compiler sagen.

Sehen Sie eine C / C ++ Header als Buchinhaltsverzeichnis

Der beste Weg ist in einem gemeinsamen Ort, um den benötigten Code zu setzen. Die „Schnittstelle“, wenn Sie möchten. Dies wird in der Regel in einer Header-Datei erfolgen, die so genannten Header, da dies in der Regel nicht eine unabhängige Quelldatei. Der Header ist nur eine Datei, deren Ziel es ist, in wahre Quelldateien enthalten (vom Präprozessor das heißt kopiert / eingefügt) werden.

Im Wesentlichen scheint es Sie zweimal ein Symbol deklarieren (Funktion, Klasse, was auch immer). Das ist fast eine Häresie im Vergleich zu anderen Sprachen.

Sie sollten es als ein Buch sehen, die mit einer Übersichtstabelle, oder einen Index. In der Tabelle haben Sie alle Kapitel. Im Text haben Sie die Kapitel und dessen Inhalt.

Und manchmal, du bist einfach nur glücklich, Ihnen die Kapitel-Liste haben.

In C ++, dies ist der Header.

Was ist mit dem DLL?

Also, zurück zu dem DLL-Problem: Das Ziel einer DLL ist Symbole zu exportieren, die Ihr Code verwenden

.

So, in einer C ++ Art und Weise, müssen Sie sowohl den Code bei der Kompilierung exportieren (dh in Windows verwenden Sie die __declspec, zum Beispiel) und „veröffentlichen“ eine Tabelle, was exportiert wird (dh haben „public“ Header enthalten, die exportierte Erklärungen).

Checkliste für den Export von Funktionen:

  • Ist die Aufrufkonvention für die Anrufer geeignet? (Dies bestimmt, wie Parameter und Ergebnisse übergeben werden, und wer verantwortlich ist für den Stapel Reinigung). Sie sollten explizit Ihre Aufrufkonvention angeben.
  • Unter dem Namen wird das Symbol exportiert? C ++ muss in der Regel dekorieren ( „Mangel“) die Namen der Symbole, z.B. zwischen verschiedenen Überlastungen zu unterscheiden.
  • die Linker Sagen Sie die Funktion sichtbar als DLL Export
  • machen

Auf MSVC:

  • __stdcall (die pascal Aufrufkonvention ist) ist die typische Aufrufkonvention für exportierte Symbole -. Unterstützt von den meisten Kunden Ich denke,
  • extern "C" können Sie das Symbol C-Stil, ohne Namen exportieren Mangeln
  • Verwendung __declspec(dllexport) ein Symbol markieren exportiert werden, oder eine separate DEF-Datei verknüpfen, wobei die Symbole exportiert werden aufgelistet. Mit einer DEF-Datei können Sie auch nur durch die Ordnungs exportieren (nicht nach Namen), und ändern Sie den Namen des Symbols, das exportiert wird.

Sie müssen die Funktion either__declspec( dllexport ) oder Hinzufügen der Funktion zu einer Moduldefinitionsdatei (.def) exportieren. kompiliert dann als DLL tho Projekt.

Auf der Clientseite, haben Sie zwei Möglichkeiten. Verwenden Sie entweder eine Importbibliothek (LIB), die erzeugt wird, wenn die DLL kompilieren. Einfach die Verknüpfung mit dieser Bibliothek mit Ihrem Client-Projekt erhalten Sie Zugriff auf die von der DLL exportierten Funktionen geben. Und Sie brauchen eine Header-Datei, weil der Compiler die Signatur Ihrer Funktion wissen muss - dass es int zurückgibt und einen int. Zur Erinnerung, müssen Sie mit einer Importbibliothek (LIB) und einer Header-Datei verknüpfen, die den Header der Funktion enthält.

Ein anderer Weg ist die DLL dynamisch über WinAPI Aufruf LoadLibrary zu laden und dann GetProcAddress einen Zeiger auf die Funktion zu erhalten. Der Zeiger auf Funktion muss den richtigen Typ haben, so dass der Compiler es die richtigen Parameter geben können und die korrekte Aufrufkonvention verwendet wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top