Funktionszeiger definition <-> (extern)-Deklaration
-
extern void(*foo)(); // extern-Deklaration des Funktioneszeigers foo
void(*foo)(); // zugehörige Deklarationextern "C" void(*foo)(); //extern-Deklaration des Funktionszeigers foo der auf eine Funktion mit C-Bindung zeigt
//? zugehörige Deklaration
-
Hallo,
meines Wissens nach geht das nur mit einem typedef. Und dann auch nicht gerade intuitiv:extern "C" void foo(); extern "C" typedef void(*func)(); int main() { func p = &foo; }
Oder habe ich jetzt deine Frage missverstanden? Kann es sein, dass du statt Deklaration Definition meintest?
PS: Eine Linkage-specification darf nur im Namespace-Scope auftauchen.
PPS: Ich glaube du meintest eher das, oder?
extern "C" typedef void(*cFunc)(); extern cFunc func; // extern-Deklaration cFunc func; // zugehörige *Definition*
-
Oder habe ich jetzt deine Frage missverstanden?
ich glaube ja
beiextern "C" typedef void(*func)();
krieg ich auch nen Fehler: "Zu viele Speicherklassen in der Deklaration"
Möchte die Funktionen von ner DLL möglichs elegant (d.h. dass der Client viel tun muss) dynamisch importieren.
Hab mir das so gedacht:
- Mit 'extern' deklarier ich eine Variable ohne sie zu definieren (extern int i;)
-> ich möchte mit extern die Funktionszeigervariable deklariern.
- Gehe davon aus, dass das "C" da keinen unterschied macht
extern "C" void(*foo)();
- in einem Cpp-File muss ich jetzt meine Funktionszeigervariable noch definieren ->
- Dann müssen die Funktionen nur noch reingeladen und den Zeigern zugewiesen werden//header---------- //definition des Funktionstyps typedef void(*foo_type)(); //geht, aber kann das richtig sein? //typedef extern "C" foo_type; //geht nicht //Bekanntgabe dass es den Funktionszeiger gibt (Deklaration) //extern extern "C" foo_type foo; //mir wärs so am einleutendsden. Geht aber nicht extern "C" foo_type foo; //deklariert? oder doch definiert??? //cpp------------- //Definition der deklarierten Funktionszeigervariable foo_type foo; //so? Aber wo bleibt das "C" //extern "C" foo; //so? Aber das ist doch wieder nur eine Deklaration void loadFooDLL() { HANDLE module( LoadLibrary("meine.dll")); foo = foo_type( GetProcAddress(module,"_foo")); //initialisieren der Funktionezeigervariable }
Ohne das "C" wär mir alles klar. Aber mit dem "C"? Entweder extern "C" ist eine extern-Deklaration, wie definier ich dann meine Funktionszeigervariable, oder extern "C" ist keine extern-Deklaration im eigentlichen Sinne, aber wie mach ich dann eine solche???
[edit]
Dein Nachtrag: genau das hab ich gemeint
Nur leider mag das wie gesagt mein C++Builder nicht
Der Comeau compilierts aber
und jetzt
-
So nimmt ers:
//header---------- extern "C"{ typedef void(*foo_type)(); extern foo_type foo; } //cpp------------- extern "C"{ foo_type foo; }
Müsste dasselbe sein, oder?
[Edit]
Ah, jetzt kapier ich, warum Du mich nicht kapiert hastHab oben vor lauter nachdenken immer nur *Deklaration* geschrieben!
-
Hallo,
mein nachträglich hinzugefügtes Beispiel macht genau das, was du willst.
Also
a) Eine Variable vom Typ "Zeiger auf Funktion mit C-Linkage" deklarieren, aber nicht definieren:// Header.h extern "C" typedef void (*PointerToCFunc)(); extern PointerToCFunc myFuncPointer;
b) In einer cpp-Datei den zuvor deklarierten Zeiger definieren:
#include "header.h" PointerToCFunc myFuncPointer;
So ist das Standard-C++. Wenn dein Compiler das nicht schluckt, dann ist das ein Fehler. Was du dagegen machen kannst, weiß ich leider auch nicht.
Allerdings unterscheiden viele Compiler typmäßig nicht zwischen einer normalen C++ Funktion und einer Funktion mit C-Linkage. D.h. du kannst da sowas machen:
extern void (*myFuncPointer)(); // Deklaration in der h void (*myFuncPointer)(); // Definition in der cpp-Datei extern "C" void cFunc(); void cppFunc(); int main() { myFuncPointer = cFunc; myFuncPointer = cppFunc; }
-
Ok. Wir haben ein Synchronisationsproblem
-
Müsste dasselbe sein, oder?
Yep. Wenn der BCC das mitmacht, kannst du imo sogar den extern "C"-Block in der cpp-Datei weglassen.
-
muchas gracias!
-
Ich versteh jetzt nicht ganz was du willst, könnte es nicht einfac sein, dass du dynamisch eine gamz gewöhnlich Funktion linken willst? Fals ja dann geht das so für Win32:
Hier die definition (gehört in die dll). Das __stdcall haut die Namesverschlüsselung weg:extern "C" void __stdcall __declspec(dllexport) foo();
Hier nun die Definition (gehört auch in die DLL):
extern "C" void __stdcall __declspec(dllexport) foo(){ //... }
Und um nun at runtime, also dynamisch, zu linken tuts du das hier:
HINSTANCE dll=LoadLibrary("dll name"); void (__stdcall *foo)()=(void (__stdcall *)())GetProcAddress(dll,"foo"); (*foo)();//Aufruf FreeLibrary(dll);
Kleiner Tip wenn du nicht weist wie dein Compiler ein Funktions Pointer gerne declarirt hat dann weis einfach den pointer (also in diesem Fall foo) einem char* oder irgend einem garatiert incompatible Typ zu. Nun wird der Kompiler meckern:
Cannot convert 'void (__stdcall *)()' to 'char *'
(oder so ähnlich) und dann hast du den Typ. Error sind auch manchmal was schönes.