2009-09-17 10 views
5

Hey Leute, ich habe ein paar kurze Fragen über Windows DLL.Frage zu DLL Export/Import und Extern unter Windows

Grundsätzlich verwende ich die ifdefs, um die dllexport und dllimport zu behandeln, meine Frage ist tatsächlich in Bezug auf die Platzierung der dllexports und dllimports sowie extern keyword.

Ich setze die dllimports/dllexports auf die Header-Dateien, aber muss ich die dllexport und dllimports auf die aktuelle Definition setzen?

Wie wäre es mit typedefs?

setze ich den dllimport/dllexport vor?

extern dllexport func1(); 

One umfasst die:

extern "C" { 

dllexport void func1(); 

} 

Ich habe auch es so verwendet wird, gesehen: wie in

dllexport typedef map<string, int> st_map 

auch das Schlüsselwort extern in Bezug auf habe ich es verwendet wird, so gesehen "C" und das andere nicht, meine Frage ist was ist der Unterschied und muss ich es verwenden? Wenn ich es dann verwende, verwende ich es sowohl für dllexport als auch für dllimport, muss ich es auch für die Header-Dateideklarationen und die Definitionen verwenden?

Mein Projekt wird freigegebene Bibliothek sein, es enthält mehrere Klassendateien, die ich exportieren möchte, einige Typdefs, die ich exportieren möchte und einige globale Funktionen, die ich auch alle in eine DLL exportieren möchte.

Wer erleuchte mich bitte?

EDIT:

Okay, ich dachte, ich werde einen kleinen Auszug aus nach, was ich getan habe, auch feststellen, dass ich die Bibliothek bin Gebäude sowohl für Linux und Windows, damit ich einen Scheck für das tun:

mydll.h 

#ifdef WINDOWS 
# ifdef PSTRUCT_EXPORT 
# define WINLIB __declspec(dllexport) 
# else 
# define WINLIB __declspec(dllimport) 
# endif 
#else 
# define WINLIB 
#endif 

WINLIB void funct1(); 

Jetzt im Quellcode:

mydll.cpp 

#define PSTRUCT_EXPORT 

void funct1() <---- do i need to add WINLIB in front of it? 
         Or is doing it in the header enough? 

Antwort

7

Zuerst müssen Sie Typdefs nicht importieren oder exportieren. Solange sie in den Header-Dateien sind, die beide Seiten verwenden, bist du gut. Sie müssen Funktionen und Klassendefinitionen importieren/exportieren.

Vermutlich verwenden Sie die gleichen Header-Dateien sowohl für den Import und Export-Code, so dass Sie einige Make-Datei Magie tun könnte einen Präprozessormakro auf jeder Seite zu definieren, gehen Sie dann so etwas wie dieses:

#if defined(LIBRARY_CODE) 
#define MYAPI __declspec(dllexport) 
#else 
#define MYAPI __declspec(dllimport) 
#endif 

extern MYAPI void func1(); 
class MYAPI MyClass { 
    ... 
}; 

In Bezug auf C vs. C++ Funktionen, können Sie dies tun:

#if defined(__cplusplus__) // always defined by C++ compilers, never by C 
#define _croutine "C" 
#else 
#define _croutine 
#endif 

extern _croutine void function_with_c_linkage(); 

Stellen Sie sicher, dass diese Header-Datei von Ihrer C++ Quelldatei importieren (die Implementierung dieser Funktion enthalten) oder der Compiler weiß nicht, ihm C-Bindung zu geben.

+0

Okay, ich habe etwas sehr ähnliches außer dem externen Keyword-Bit. Ich habe ähnliche Makros in allen meinen Klassendateien definiert. Also wird das externe verwendet, um Unterstützung für C-Compiler bereitzustellen? Mein Projekt ist hauptsächlich C++ –

+0

muss ich auch die dllimport/export-Anweisungen in der Definition hinzufügen? –

+0

Der einzige Grund, warum Sie das externe "C" Zeug benötigen, ist, wenn Sie versuchen, eine C++ - Funktion von C-Code zu verknüpfen. Im Grunde können Sie das externe "C" Zeug ignorieren, bis Sie Linker-Fehler bekommen. –

2
  1. typedefs brauchen keine dllimport/dllexport, es ist nur eine Definition
  2. dllimport/dllexport sind nicht Standard, denken Sie daran, ein Makro für andere Plattformen/Compiler
  3. auch kümmern sich um die Aufrufkonvention (cdecl, stdcall, ...) verwendet sonst werden Sie in Probleme geraten (wenn Sie Interoperable mit Visual Basic verwenden müssen stdcall)
  4. umschließen innerhalb von "C", so dass Ihre Lib aus C++ - Programmen verwendet werden kann, verwenden Sie #ifdef __cplusplus, um es nur für C++ sichtbar zu halten.

Sehen Sie sich verschiedene OpenSource-Bibliotheken an. Dort finden Sie viele Beispiele, wie Sie einen guten Bibliothekskopf erstellen können. Es könnte Probleme mit Namensdekoration im Fall von C++ ohne das externe "C" geben.

+0

Die meisten Sachen, die ich in die DLL setze, sind Klassen, also möchte ich hauptsächlich, dass das hauptsächlich unter C++ kompiliert wird, also sollte ich exter "c" vermeiden? –

+0

In diesem Fall ja - Sie dürfen nicht extern "C" verwenden. Aber sei dir bewusst, dass du wegen der Namensdekoration andere dazu zwingst, den gleichen Compiler zu benutzen, um deine lib zu benutzen. Um dies zu vermeiden, könnten Sie eine C-Bibliothek und einen C++ - Wrapper dafür bereitstellen, der als Quellcode in Kundenprojekte integriert werden kann. – jdehaan

Verwandte Themen