Pingu
28-04-2007, 09:17
Ich habe gerade ein kleines Problem, sonst würde ich hier wohl auch nicht schreiben ;).
Ich habe ein Modul/Library/Treiber mit dem ich eine Hardware zum Senden und Empfangen von Nachrichten ansprechen kann. Dieser Treiber hat eine Initialisierungsfunktion. In der Initialisierungsfunktion kann ich eine Callback übergeben, die aufgerufen wird, wenn neue Nachrichten zur Verfügung stehen.
extern int DLLIMPORT InitBoard(UINT16 board_seg, t_UsrRxIntHdlr fp_int_hdlr, t_UsrExcHdlr fp_exc_hdlr);
typedef void (*t_UsrRxIntHdlr)(UINT16 count, CAN_OBJ *p_obj);
typedef void (*t_UsrExcHdlr)(FUNC_NUM, int, int, char *);
In meinem Programm kann es jetzt aber passieren, dass ich diesen Treiber mehrfach instanziieren muss, weil ich mehrere Hardwareinterfaces habe. Prinzipiell sollte das kein Problem sein. Konkret sehe ich aber ein Problem: für die Callbackfunktion(en) kann ich keinen eigenen Datenpointer übergeben. Wenn somit die Callback aufgerufen wird, weiß ich nicht, von welchem konkreten Interface der Aufruf und damit die Daten kommen.
Mir ist eine Idee gekommen eine Art Template-Funktion zu definieren, die ich dann instanziieren kann. Ich würde gerne so etwas machen (Pseudo code):
void RxCallbackTemplate(UINT16 count, CAN_OBJ *p_obj) {
void *handle;
RxCallbackWithHandle(handle, count, p_obj);
}
InitTreiber() {
// do stuff and generate myPrivateHandle
RxCallback = Instanziiere(RxCallbackTemplate);
RxCallback->handle = myPrivateHandle;
InitBoard(board_seg, &RxCallback, NULL);
}
Eigentlich müßte es soch theoretisch möglich sein, indem ich mir eine Template-Funktion als Inline-Assembler definiere. Der Inline-Assembler müsste nur den Aufruf einer anderen Funktion realisieren. Dann reserviere ich etwas Speicher; kopiere den Inline-Assembler-Code dahin; ändere ein paar Adressen (setze das Handle) und übergebe die Speicher-Adresse als Callback an das InitBoard(). So müßte es doch gehen?
Das ganze soll, wenn möglich, unter allen Windows-Versionen (95 bis XP, Vista) laufen.
Ich habe leider kein C++ oder ähnliches zur Verfügung. Es muss in simplen ANSI-C möglich sein, da mein Compiler der Compiler von National Instruments LabWindows/CVI ist, der nur ANSI-C kann.
Weiß jemand wie man so etwas realisiert? Hat jemand eine andere Idee, das besser zu machen? Oder kann mir jemand Tips geben, wonach ich mit Google nach einer Lösung suchen kann?
Danke
Pingu
Ich habe ein Modul/Library/Treiber mit dem ich eine Hardware zum Senden und Empfangen von Nachrichten ansprechen kann. Dieser Treiber hat eine Initialisierungsfunktion. In der Initialisierungsfunktion kann ich eine Callback übergeben, die aufgerufen wird, wenn neue Nachrichten zur Verfügung stehen.
extern int DLLIMPORT InitBoard(UINT16 board_seg, t_UsrRxIntHdlr fp_int_hdlr, t_UsrExcHdlr fp_exc_hdlr);
typedef void (*t_UsrRxIntHdlr)(UINT16 count, CAN_OBJ *p_obj);
typedef void (*t_UsrExcHdlr)(FUNC_NUM, int, int, char *);
In meinem Programm kann es jetzt aber passieren, dass ich diesen Treiber mehrfach instanziieren muss, weil ich mehrere Hardwareinterfaces habe. Prinzipiell sollte das kein Problem sein. Konkret sehe ich aber ein Problem: für die Callbackfunktion(en) kann ich keinen eigenen Datenpointer übergeben. Wenn somit die Callback aufgerufen wird, weiß ich nicht, von welchem konkreten Interface der Aufruf und damit die Daten kommen.
Mir ist eine Idee gekommen eine Art Template-Funktion zu definieren, die ich dann instanziieren kann. Ich würde gerne so etwas machen (Pseudo code):
void RxCallbackTemplate(UINT16 count, CAN_OBJ *p_obj) {
void *handle;
RxCallbackWithHandle(handle, count, p_obj);
}
InitTreiber() {
// do stuff and generate myPrivateHandle
RxCallback = Instanziiere(RxCallbackTemplate);
RxCallback->handle = myPrivateHandle;
InitBoard(board_seg, &RxCallback, NULL);
}
Eigentlich müßte es soch theoretisch möglich sein, indem ich mir eine Template-Funktion als Inline-Assembler definiere. Der Inline-Assembler müsste nur den Aufruf einer anderen Funktion realisieren. Dann reserviere ich etwas Speicher; kopiere den Inline-Assembler-Code dahin; ändere ein paar Adressen (setze das Handle) und übergebe die Speicher-Adresse als Callback an das InitBoard(). So müßte es doch gehen?
Das ganze soll, wenn möglich, unter allen Windows-Versionen (95 bis XP, Vista) laufen.
Ich habe leider kein C++ oder ähnliches zur Verfügung. Es muss in simplen ANSI-C möglich sein, da mein Compiler der Compiler von National Instruments LabWindows/CVI ist, der nur ANSI-C kann.
Weiß jemand wie man so etwas realisiert? Hat jemand eine andere Idee, das besser zu machen? Oder kann mir jemand Tips geben, wonach ich mit Google nach einer Lösung suchen kann?
Danke
Pingu