PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Variablen in DLLs anlegen?


Einfachkrank
2004-10-05, 18:54:57
Servus,

ich habe die ganze Zeit eine kleine Bibliothek meiner Funktionen
zum Programmieren verwendet und möchte diese nun in eine DLL
packen...
In der Bibliothek habe ich globale Funktionszeiger angelegt, die
in einer Header deklariert werden, ungefähr so:
// file: header.h
extern void (func*) (void);

// file: header.cpp
void (func*) (void);

// in einer externen Datei:
# include "header.h"

// ...
func();
Kann ich das in einer DLL umsetzen? Quasi, dass die eine globale Variable, die durch die Header bekannt ist mit in die DLL exportieren?

MFG Einfachkrank

Einfachkrank
2004-10-06, 18:52:46
Hab ich mich nicht verständlich ausgedrückt oder hat keiner ne Idee? Wo sind die Gurus? :D

zeckensack
2004-10-06, 18:59:58
Du brauchst zwei verschiedene Header. Einen zum exportieren in die DLL:__declspec(dllexport) void funktion(void);
__declspec(dllexport) int variable;
__declspec(dllexport) void (*funktionszeiger)(void);
Und einen um aus der DLL zu importieren:__declspec(dllimport) void funktion(void);
__declspec(dllimport) int variable;
__declspec(dllimport) void (*funktionszeiger)(void);Den ersten inkludierst du beim Bauen der DLL. Den zweiten inkludierst du in das Projekt, das die DLL benutzt.

Bonuspunkte gibt's, wenn du es mit nur einer einzigen Header-Datei machst, und die Unterschiedung durch den Präprozessor löst.

Einfachkrank
2004-10-06, 23:00:02
Das Import/Export Prinzip bei Dlls kannte ich schon, nur ich wusste nicht, ob das eben auch mit Variablen funktionieren würde. Als ich es versuchte, tat es dies nämlich nicht, aber jetzt werd ich es weiter versuchen :)


# define BUILD

# ifdef BUILD
# define _DLL __declspec(dllexport)
# else
# define _DLL __declspec(dllimport)
# endif

Gibt´s dafür Bonuspunkte? :)

zeckensack
2004-10-08, 08:46:50
Das Import/Export Prinzip bei Dlls kannte ich schon, nur ich wusste nicht, ob das eben auch mit Variablen funktionieren würde. Als ich es versuchte, tat es dies nämlich nicht, aber jetzt werd ich es weiter versuchen :)Im Prinzip gibt's hier keine Unterscheidung zwischen Variablen und Funktionen.

Die größte Stolperfalle dürfte hier das "extern" sein. Für Funktionensdeklarationen in einem Header braucht man das nie. Bei Variablen gibt's Probleme, denn wenn man ohne "extern" eine Variable in einem Header deklariert, wird sie auch dort angelegt ("definiert"), was man idR nicht will.


# define BUILD

# ifdef BUILD
# define _DLL __declspec(dllexport)
# else
# define _DLL __declspec(dllimport)
# endif

Gibt´s dafür Bonuspunkte? :)Ja, dafür gibt's Punkte.
Ich gehe mittlerweile davon aus, dass der Präprozessor schwierig zu verstehen ist, weil trotz vieler Mühen so gut wie niemand damals meinen Header verstanden hat. Auszug:#ifdef BROT_CORE_EXPORTS
#define BROT_CORE_API __declspec(dllexport)
#else
#define BROT_CORE_API __declspec(dllimport)
#endif

#define BROT_CALL

#ifdef BROT_CORE_EXPORTS
class Context;
typedef Context* bc_context;
#else
typedef unsigned int bc_context;
struct Place {ubyte dont_touch[100];};
#endif


#define BROT_FUNCTION(name,return_type,argument_list) BROT_CORE_API return_type BROT_CALL name argument_list

extern "C"
{
////context management
//create a new context for the core functions
//will try to consume no more than 'megs' megabytes of memory for the history functions
BROT_FUNCTION(bc_create_context,bc_context,(int megs));
//reset context to fresh state, but keep it around
BROT_FUNCTION(bc_reset_context,void,(bc_context context));
//destroy context
BROT_FUNCTION(bc_delete_context,void,(bc_context* context));

////misc
//return string description of a generator type, given by enum
BROT_FUNCTION(bc_describe_generator,const char* const,(int generator_type));
<...>
}

Einfachkrank
2004-10-09, 17:25:17
Mit extern "C" kann ich nichts anfangen und warum du einfach BROT_CALL definierst und es zwischen Rückgabewert und Funktionsname packst.

Xmas
2004-10-09, 20:55:47
Mit extern "C" kann ich nichts anfangen und warum du einfach BROT_CALL definierst und es zwischen Rückgabewert und Funktionsname packst.
extern "C": http://msdn.microsoft.com/library/en-us/vclang/html/_pluslang_linkage_to_non.2d.c.2b2b_.functions.asp

BROT_CALL soll für die Calling Convention der Funktionen stehen. Da das leer ist, soll einfach die Standard Calling Convention des Compilers verwendet werden (üblicherweise cdecl). Das ist nicht nötig (ist ja leer), aber sauberer wenn es später geändert werden soll.

Einfachkrank
2004-10-10, 15:42:25
Das extern mit dem "C" heißt also, dass es erlaubt ist die deklarierte Funktion der Run-time Libary hinzuzufügen, oder wie? Ich bin nicht gerade der Crack in Englisch :)

__cdecl wird doch normalerweise standardmäßig vom Compiler bei Funktionen angehängt, oder? Ich kenn mich da nicht ganz so gut aus, aber das hat doch dann was mit dem aufräumen und so zu tun? Wobei das __stdcall das Gegenteil ist, oder irgendwie war da was :)

Einfachkrank
2004-12-23, 12:55:32
*DenThreadRauskram* *Ächz* :)

Also, Anlegen von Variablen in DLL Dateien hat immer noch net richtig funktioniert.

so hab ichs stehn:

// header:
extern _DLL int Variable;

// source:
_DLL int Variable = 0;
Ist das rein formal so richtig?

Crushinator
2004-12-27, 12:50:29
Kleiner Auszug aus einer .h Datei eines Projektes von mir, bei dem sich die DLL und EXE Variablen teilen. Nur die DLL wird mit THEPRG_EXPORTS kompiliert.


#ifdef THEPRG_EXPORTS
#define THEPRG_API __declspec(dllexport)
#else
#define THEPRG_API __declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

THEPRG_API int iCPUStat;

#ifdef __cplusplus
}
#endif /* __cplusplus */

Siehe auch http://www.mainzelahr.de/smile/schilder/guckstduhier.gif da (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/HTML/_core_using___declspec.28.dllimport.29_.and___declspec.28.dllexport.29.asp).

Einfachkrank
2004-12-28, 00:18:22
Es funktioniert seit meiner letzten Variante, aber trotzdem vielen danke!

Ist nur komisch ... wenn ich die DLL Variablen in einer Header Datei deklariere spuckt mir der Compiler aus, dass die Variable schon mehrmals deklariert wurde, wie als würde ich das

# ifndef _HEADER_H
# define _HEADER_H
// header bla
# endif
zur Vermeidung von mehrfacher Einbindung weglassen. Aber ich habe die Variablen in der Header jetzt mit extern gekennzeichnet und sie in den Quellcodedateien des DLL Projektes deklariert.