C++ Kryptik...
-
@Hustebär – Danke für Deine schnelle Antwort – dann sind wir wohl schon zwei, die den fraglichen Zusammenhang nicht nachvollziehen können.
Der im Wesentlichen mir nicht nachvollziehbare Aspekt ist diese Zeile (die 3 Punkte sollten sich nicht auf die ellipsis notation beziehen – ich habe stattdessen dem Original entsprechend, ein weiteres „int“ ergänzt):
typedef void (callConvention *handler)(void *efgh, int Parameter, int Parameter1);
Wenn ich dazu die Suchmaschine bemühe, finde ich zwar etwas Ähnliches – etwa das hier: (http://stackoverflow.com/questions/3982470/what-does-typedef-void-something-mean) –
aber dort scheinen auch verschiedene Meinungen zu existieren. Vielleicht gibt es ja doch jemanden, der mir zumindest die genannte Zeile erklären könnte.
MfG.
-
Ne ich weiss genau was diese Zeile soll, nur nicht was du willst.
Die Zeile definiert einen Funktionszeiger-Typ.
Der Typ heisst "handler" und so ein "handler" kann dann auf eine Funktion mit folgender Signatur zeigen:void handler_funktion(void *efgh, int Parameter, int Parameter1);
(Die Parameternamen sind in beiden Fällen nur Dekoration, die könnte man genau so gut weglassen)
Genau so einen "handler" kann man der Funktion "Init" übergeben, der Parameter heisst dort "z_handler".
Aber jetzt...
Wie ich eingangs sagte, möchte ich den Wert "Parameter" für weitere Verwendungen gerne extrahieren ,wobei als Handikap nur "Dllimport" zum Einbinden der Funktion "Init" zur Verfügung steht.
WTF soll das heissen? Das ist kein verständlicher Satz, und ich hasse es zu raten.
Ich hab zwar ne gute Vermutung was du willst, aber versuch bitte es nochmal deutlicher zu formulieren.
-
@hustbaer – vielen Dank für die Antwort.
Genau so einen "handler" kann man der Funktion "Init" übergeben, der Parameter heisst dort "z_handler".
Könnte es sein, dass dadurch dem Parameter ein Wert zugewiesen werden könnte?
Eigentlich möchte ich die Funktion „Init“ mittels Dllimport in cli- basierter Programmierung verwenden. Ich brauche zur Verwendung der anderen Funktionen besagter TreiberDll den Wert von Parameter – zumindest ist nach dem Aufruf der Init – Funktion dem Parameter in dem besagten C++ Originalprojekt ein 32-bit Wert zugewiesen, der an sämtliche andere, relevante Treiberfunktionen übergeben wird. Ich hatte mich nun gefragt, wie die Zuweisung des Wertes an Parameter von statten gehen soll – meinen derzeitigen Wissenstand diesbezüglich hatte ich in meinem ursprünglichen Beitrag gepostet.
MfG
-
7x7-7 schrieb:
@hustbaer – vielen Dank für die Antwort.
Genau so einen "handler" kann man der Funktion "Init" übergeben, der Parameter heisst dort "z_handler".
Könnte es sein, dass dadurch dem Parameter ein Wert zugewiesen werden könnte?
.....hä?
Du kannst Init() aufrufen. Da kannst du übergeben was du willst.
Und die DLL kann dann deine übergebene "handler" Funktion aufrufen. Irgendwann mal. Wenn sie mag. Oder auch nicht.
Und wenn sie's tut kann sie ihrerseits dann Parameter übergeben. "Zugewiesen" wird hier aber nichts.Was du schreibst ist für mich einfach nur wirr.
Eigentlich möchte ich die Funktion „Init“ mittels Dllimport in cli- basierter Programmierung verwenden.
Immer noch wirr. Was ist "cli-basierte Programmierung"? CLI wie in "command line interface"? Oder wie in C++/CLI? Oder doch eher cli wie in "ich schreib da einfach mal drei Buchstaben hin weil Abkürzungen wirken immer professionell"?
Ich brauche zur Verwendung der anderen Funktionen besagter TreiberDll den Wert von Parameter
Welche andere Funktion? Du schreibst nix von einer anderen Funktion.
zumindest ist nach dem Aufruf der Init – Funktion dem Parameter in dem besagten C++ Originalprojekt ein 32-bit Wert zugewiesen,
???
Es gibt kein "besagtes" Objekt - du hast nie irgendwas von irgendeinen Objekt gesagt. Und selbst wenn wüsste ich nicht was für ein Objekt, wer wann was damit macht etcpp.der an sämtliche andere, relevante Treiberfunktionen übergeben wird.
Aha. Schön für dich zu wissen dass es sich anscheinend um irgend einen Treiber handelt.
Ich hatte mich nun gefragt, wie die Zuweisung des Wertes an Parameter von statten gehen soll – meinen derzeitigen Wissenstand diesbezüglich hatte ich in meinem ursprünglichen Beitrag gepostet.
Ne, du hast in deinem Beitrag einen Haufen wirres Zeug geschrieben. Das macht für dich vielleicht alles Sinn, weil DU ja die ganzen Dinge weisst die DU UNS nicht dazuschreibst.
----
Dinge abstrakt zu formulieren scheint nicht deine Stärke zu sein, also mach mal Klartxt. Also worum geht es hier und was konkret willst du machen?
Und welches OS, welche Programmierspracht etcpp.
-
7x7-7 schrieb:
Genau so einen "handler" kann man der Funktion "Init" übergeben, der Parameter heisst dort "z_handler".
Könnte es sein, dass dadurch dem Parameter ein Wert zugewiesen werden könnte?
Nein, das geht nicht. Du musst den Parameter neben der Funktion auch noch mit übergeben.
Das ist auch kein MFC. (und somit hier offtopic)
Das ist auch kein C++. (und somit hier offtopic)
Das ist pures C (mit DLL Gefrickel).Z.B. kannst du den void* dazu nutzen, der kann einen Zeiger auf deinen Parameter enthalten oder einen Zeiger auf eine Struktur, die deinen Parameter direkt enthält:
typedef void (*handler)(void *efgh, int Parameter); int Init(void * abcd, handler z_handler) { int *iz = abcd; ... z_handler(abcd,*iz); ... } oder int Init(void * abcd, handler z_handler) { struct bla { int x; char c; ... } *struktur = abcd; ... z_handler(abcd,struktur->x); ... } oder du übergibst einen weiteren Parameter an die Init Funktion, den du dann direkt verwenden kannst: int Init(void * abcd, handler z_handler, int p) { ... z_handler(abcd,p); ... }
-
Wenn ich auch mal raten darf:
Er will die DLL in einem C++/CLI Projekt verwenden und weiss nun nicht, wie er eine entsprechende DllImport-Direktive für die Funktion "Init" formulieren soll, weil die Init-Funktion unter anderem eben einen Funktionszeiger übergeben bekommt.
-
Man kann in .NET keine Funktionszeiger an natives C++ übergeben.
Man muss eine Wrapperklasse schreiben in C++/CLI. Am besten mit einem entsprechenden Delegator.
Dann kann man auch die DLL einfach als Assembly in ein C# Projekt packen.
-
Martin Richter schrieb:
Man kann in .NET keine Funktionszeiger an natives C++ übergeben.
Dafür kann man Funktionszeiger an native C Code übergeben (einfach nen passenden delegate übergeben). Und mehr braucht er hier ja auch nicht.
-
Hallo ,
erstmal möchte ich mich für die teilweise sehr interessanten Interpretationen, die nun doch hinzugekommen sind, bedanken.
Primär geht es mir darum, einen Zusammenhang in einem mir vorliegenden MFC Projekt zu verstehen. Dieser Zusammenhang bezieht sich möglicherweise auf die Initialisierung einer Hardware (um die es mir im Eigentlichen geht). Ich darf allerdings keine Originalbausteine aus dem Originalprojekt veröffentlichen – daher bemühe ich mich, erneut den Zusammenhang mit vielleicht etwas griffigeren Bezeichnern darzustellen (Hinweise erbeten, falls sinnentstellende Tippfehler enthalten sind):Inhalte aus HEADER6:
#define CALLconvention __stdcall typedef void (CALLconvention *DevHandler)(void* par1, int par2, int par3); enum DRIVERSTATE { OK };
Inhalte aus HEADER5:
class HardwaredeviceOBERgruppe { public: static HardwaredeviceOBERgruppe * CreateInstance(...spezifisches...); HardwaredeviceOBERgruppe (); virtual ~ HardwaredeviceOBERgruppe (); //1000sende virtuelle Funktionen…. }
Inhalte aus HEADER4:
#include "header5.h" #include "header6.h" //diverse #include “*lib.h” Anweisungen class Hardwaredevicegruppe : public HardwaredeviceOBERgruppe { Hardwaredevicegruppe (); virtual ~ Hardwaredevicegruppe (); //1000sende virtuelle Funktionen und unter unter anderem: virtual DRIVERSTATE Init(DevHandler Handler1, …………); virtual Treiberfunk1 (int par2, ………); ;}
Inhalte aus HEADER3:
#include "header4.h" class Hardwaredevice: public Hardwaredevicegruppe { public: static * Hardwaredevice CreateInstance(…spezifisches1…); //circa 500 virtuelle Funkionen };
Inhalte aus HEADER2:
#include "header3" class App2: public Hardwaredevice { public: App2 (CWnd* pParent = NULL); ~App2(); private: HardwareDevice *DEV1; static void CALLconvention HandlerStatic(void* par1, int par2, int par3); void Handler(int par2, int par3); };
Inhalte aus CPP2-Datei:
#include "header2" BOOL App2::OnInitDialog() { DEV1 = App2::CreateInstance(…Firmenspezifisch…); return true; } void App2::HandlerStatic(void *par1, int par2, int par3) { ((App2 *)par1)->Handler(par2, par3); } void App2::Handler(int par2, int par3) { DEV1-> Treiberfunk1 (par2,………); } void App2::OnBnClicked() { DEV1->Init(HandlerStatic,…,…, this); }
Inhalte aus HEADER1:
class App1: public CWinApp { public: App1(); public: virtual BOOL InitInstance(); };
Inhalte aus CPP1-Datei:
#include "header1" App1::App1 () { // leer } App1 theApp; BOOL App1::InitInstance() { CWinApp::InitInstance(); App2 dlg; m_pMainWnd = &dlg; }
@MORLE: Ja in der Tat, so etwas ist mir durch den Kopf gegangen. Aber möglicherweise wird es nicht funktionieren.
@WUTZ: Das mir vorliegende Projekt ist ein MFC Projekt. Da ich selbst die Verwendung von MFC vermeide, kann ich nicht sagen, ob es sich allerdings dabei nicht vielleicht doch um
pures C (mit DLL Gefrickel).
handelt.
Die Funktion „Init“ wird wie alle anderen Funktionen aus einer sehr großen TreiberDll importiert. Da alle anderen Treiberfunktionen den Parameter „par2“ benötigen, interessiert mich nun, wie der programmtechnische Zusammenhang (s.o.) zu diesem Paramter kommt.
Vielen Dank schonmal,
MfG.
-
Na HandlerStatic ist eine Handler-Funktion, die von der Treiber-DLL aufgerufen wird. Und die Treiber-DLL gibt diesem Handler ein "par2" als Parameter mit.
Was auch immer "par2" ist.Aus dem Code den du hier zeigst geht auch keine Möglichkeit hervor sonst irgendwie an den "par2" Wert zu kommen, ausser eben darauf zu warten dass ein Handler aufgerufen wird.
-
Ich glaube das größte Problem ist, das keiner genau weiss was du eigentlich willst oder vor hast.
Weiterhin verstehe ich nicht, wieso Dir deine Frage nicht einfach jemand von deiner Firme beantwortet. Du musst ja mit jemanden schon drüber gesprochen haben um zu wissen, dass du dies und jenes hier nicht posten darfst oder zumindest einen Ansprechpartner haben.
Die Antwort auf dein Problem sollte sich aber finden lassen, indem Du dich einfach mal in das Thema "Callback-Funktion" einarbeitest. Da müsste sich reichlich Material mit Google finden lassen.
-
Hallo Leute,
vielen Dank für die Interpretationen – ich konnte das Ganze halbwegs nachvollziehen und dann schließlich mit Hilfe dieses Artikels:
http://msdn.microsoft.com/en-us/library/367eeye0.aspx
auch in einem C++/CLI basierenden Programm umsetzen. Der Zeiger „cb“ aus dem Beispiel
ANSWERCB cb = static_cast<ANSWERCB>(ip.ToPointer());
kann an eine, über “Dllimport” importierte unmanged Funktion übergeben werden, die dann in der Lage ist, die in dem Beispiel als „GetNumber“ bezeichnete managed Funktion aufzurufen.
Das war im Prinzip die Antwort auf die mir anfangs unbekannte Fragestellung.
MfG.
PS: Offen bleibt allerdings noch die Frage, ob es dabei um eine MFC oder C++/CLI relevante Thematik handeln würde.