Funktionszeiger

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

Noobody

Betreff: Funktionszeiger

BeitragSo, März 01, 2009 22:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie der Titel schon sagt, möchte ich gerne den Funktionszeiger auf eine Blitz - Funktion haben.
Dass es ein schwieriges Unterfangen ist, ist mir klar, jedoch ist es einen Versuch wert Razz

An sich müsste es möglich sein, wenn auch kompliziert. Angenommen, ich habe meine Funktion und rufe gleich zu beginn eine Funktion einer DLL auf.
Beim Aufrufen der DLL - Funktion müsste Blitz ja die Rücksprungadresse auf den Stack schieben, damit an die richtige Stelle zurückgesprungen wird, wenn die DLL - Funktion endet.
Nun wäre es doch möglich, in der Funktion der DLL per ASM auf den Stack zuzugreifen, die Rücksprungadresse auszulesen und diese zurückzuliefern.
Die Rücksprungadresse müsste dann auf die Anweisung nach dem Aufruf der DLL - Funktion zeigen, wäre also sehr nahe an der Adresse der Funktion.

Ein kurzer Beispielcode, um zu zeigen, was ich meine:
Code: [AUSKLAPPEN]
Function BlitzFunktion()
     Adresse = DLL_Funktion()
     
     [lokale Variablen definieren, restlicher Code der Funktion]
End Function

int DLL_Funktion() {
     return Rücksprung_Adresse
}


Der Nachteil ist natürlich, dass in jeder Funktion, von der man die Adresse wissen will, am Anfang noch die Funktion der DLL aufgerufen, aber das halte ich für ein übersehbares Übel.

Ist dieses Unterfangen praktikabel bzw. überhaupt möglich?
Hat das vielleicht schon jemand versucht?

Ich kann es im Moment leider nicht umsetzen, da mein ASM sehr eingerostet ist, würde es aber gerne versuchen, falls der Ansatz stimmt.
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun

Noobody

BeitragMo, März 02, 2009 15:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Sorry für den Doppelpost, aber ich habe gestern eine Weile lang herumprobiert, in Büchern geschmökert und bin schlussendlich auf eine Methode gestossen.
Ich kann nun problemlos einen Zeiger auf eine benutzerdefinierte Funktion in BlitzBasic herausfinden - nur gibt es beim Aufrufen Probleme.

Ich kann zwar die Funktion von einer DLL aus aufrufen, jedoch scheint Blitz andere Standards für den Funktionsaufruf zu verwenden als C++.
Die Funktion wird aufgerufen, jedoch stürzt Blitz bei 'Return' ab, da es offenbar andere Elemente auf dem Stack erwartet, als nach dem Aufruf durch die DLL draufliegen.

Ich habe zwar eine Lösung dafür gefunden, jedoch ist sie nicht so schön, wie ich das gerne hätte.
Wenn ich die DLL die Blitz - Funktion aufrufen lasse, merkt sich die DLL, von wo aus sie aufgerufen wurde.
Endet die Blitz - Funktion, so führt sie anstatt 'Return' eine Funktion der DLL aus, die ich mal 'ReturnInt' genannt habe. Diese Funktion springt wieder dorthin zurück, von wo aus die erste Funktion aufgerufen wurde.
Das ist nicht nur unsauber, sondern hinterlässt auch eine Unordnung auf dem Stack, was über kurz oder lang zu einem Stack Overflow führt.
Was ich jetzt also brauche, sind Informationen darüber, was genau Blitz auf den Stack pusht, wenn es eigene Funktionen aufruft, damit ich so einen Aufruf nachbauen kann.

Hier der aktuelle Code in Blitz: Code: [AUSKLAPPEN]
Global Pointer, Call

Print Test()
Print CallFunction( Pointer )
WaitKey()
End

Function Test()
   Pointer = FunctionPointer()
   
   Print "Funktioniert! Aufruf Nummer " + Call
   
   Call = Call + 1
   
   If Call = 1 Then
      Return 5
   Else
      ReturnInt( 5 )
   EndIf
End Function


Die DLL in C++: Code: [AUSKLAPPEN]
#define BBEXPORT extern "C" _declspec(dllexport)

void (__stdcall *JumpFunction)(void);

BBEXPORT int __stdcall FunctionPointer() {
   unsigned int StackPosition, Adress;

   __asm {
      mov StackPosition,esp
      mov esp,ebp
      add esp,4
      pop Adress
      mov esp,StackPosition
   }

   return Adress - 8;
}

BBEXPORT int __stdcall CallFunction( int (__stdcall *B3DFunction)(void) ) {
   unsigned int StackPosition;

   __asm {
      mov StackPosition,esp
      mov esp,ebp
      add esp,4
      pop JumpFunction
      mov esp,StackPosition
   }

   return B3DFunction();
}

BBEXPORT void __stdcall ReturnInt( int Value ) {
   __asm {
      mov eax,[Value]
   }

   JumpFunction();
}


Vielleicht hat sich schon mal jemand damit beschäftigt, ich wäre dankbar für jede Antwort.
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun

coolo

BeitragMo, März 02, 2009 18:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Wow! Das wäre das Feature, welches ich mir schon immer gewünscht habe (Das wäre bei ner Scriptengine Gold Wert, da man endlich kein dummes Select - Case Gedudel machen muss)

Außerdem habe ich nicht viel Ahnung von Assembler, jedoch kann ich mir denken, das man es doch dekompilieren könnte (weiß nicht ob das Legal ist), und dann einfach schaut was BB so auf den Stack schiebt. Ansonsten kann die vllt. Folgendes helfen: https://www.blitzforum.de/foru...t=kulissen Da hat mal Vertex ein bisschen geschaut was so alles hinter BB steckt.
http://programming-with-design.at/ <-- Der Preis ist heiß!
That's no bug, that's my project!
"Eigenzitate sind nur was für Deppen" -Eigenzitat

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group