callback procedure in Exe

Für allgemeine Fragen zur Programmierung mit PureBasic.
HPW
Beiträge: 17
Registriert: 30.08.2004 17:32

callback procedure in Exe

Beitrag von HPW »

Hallo,

Habe die Frage zunächst im franz.Forum gepostet:

https://www.purebasic.fr/english/viewto ... 13&t=71552

Kann eine purebasic.exe ProcedureDLL nutzen?
Kann ich eine purebasic Procedurevon einer Dll aus mit dem @-Adress-pointer und kompatiblen Parametern aufrufen?
Hat schon mal jemand mit einer purebasic dll einen callback in eine purebasic exe gemacht?

Grüsse,
Hans-Peter
Hans-Peter
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: callback procedure in Exe

Beitrag von RSBasic »

Ja, letztens: viewtopic.php?p=348978#p348978

Ausschnitt:

Code: Alles auswählen

MultiKBHook = OpenLibrary(0, "MultiKBHook.dll")
  If MultiKBHook
    HookID = SetWindowsHookEx_(#WH_KEYBOARD, GetProcAddress(MultiKBHook, "KeyboardProc"), MultiKBHook, 0)
    If HookID = 0
      Debug "Hook konnte nicht erstellt werden."
    EndIf
  Else
    Debug "Die DLL-Datei konnte nicht gefunden werden."
  EndIf
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
HPW
Beiträge: 17
Registriert: 30.08.2004 17:32

Re: callback procedure in Exe

Beitrag von HPW »

Hallo,

Erst mal Danke für die Antwort.
Bin mir nur nicht sicher ob das Beispiel mein Problem trifft.

In diesem Link schien mir das vielversprechend:

https://www.purebasic.fr/english/viewto ... 12&t=52807

Das schien mir meine Anforderung zu treffen.

Ich möchte aus meiner Purebaisc-Exe eine DLL laden, diese aufrufen und während der Ausführung in der DLL eine Procedure in der Main-Exe mit Paramtern aufrufen können. (Klasischer CallBack, habe es in Delphi und PdScript schon so gemacht)

Habe das aber bislang nicht ans Laufen bekommen.

Grüsse,
Hans-Peter
Benutzeravatar
HeX0R
Beiträge: 2954
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: callback procedure in Exe

Beitrag von HeX0R »

Na klar geht das, das mache ich ständig in meinem aktuellen Projekt.
Du reichst die Adresse der (main) Prozedur an die DLL, und die kann die einwandfrei aufrufen.

Das ist übrigens kein französisches Forum, das Du da verlinkt hast, und lass in Zukunft diese Cross-Postings!

Hier der Code:
Dll:

Code: Alles auswählen

Prototype.f PR_Multiply(a.f, b.f)
Global Multiply.PR_Multiply

ProcedureDLL Init(*AddressToMultiplyProcedure)
	Multiply = 	*AddressToMultiplyProcedure
	Multiply(12, 2.5)
EndProcedure
Main:

Code: Alles auswählen

Prototype PR_Init(*address)

Global Init.PR_Init

Procedure mul(a.f, b.f)
	MessageRequester("Main Program now!", "Result: " + StrF(a * b))
EndProcedure



If OpenLibrary(0, "dlltest.dll")
	Init = GetFunction(0, "Init")
	If Init
		Init(@mul())
	EndIf
	
	
	OpenConsole()
	Input()
	
	CloseLibrary(0)
EndIf
HPW
Beiträge: 17
Registriert: 30.08.2004 17:32

Re: callback procedure in Exe

Beitrag von HPW »

Hallo HeXOR,

Danke für das Beispiel. Gut zu wissen das es im reinen Purebasic Duo erst mal geht.
Nun habe ich in meinem Fall die Dll-Seite nicht in der Hand.
Ich nutze als Dll ja den newlisp-interpreter der eine generische Callback-Unterstützung hat.
Der ruft die Funktion auch mittels der Adresse der Procedure auf.
Die Parameter sind aber immer Pchar im Utf8 Format. Das hätte ich ja in Purebasic-Main in der Hand.
Morgen werde ich versuchen anhand deines Beispiels meinen Test zu verändern.

Entschuldigung das ich das Forum als französisches Forum bezeichnet habe.
Habe mich von der Domain purebasic.fr dazu verleiten lassen.
Also besser das internationale Forum?
Aber es sind doch unterschiedliche Communitys oder?
Es mag ja eine Menge User geben die beide Foren lesen.
Aber erreiche ich mit einem Hilfe-Ersuchen in beiden Foren nicht einfach mehr Experten.
So hat zum Beispiel in einem anderen Thread zu newlisp Fred im internationalem Forum geantwortet und mich auf den richtigen Weg gebracht. Ich bin für jede Hilfe dankbar. Ob international oder hier im deutschen Forum. Ist das Falsch?

Grüsse,
Hans-Peter
Hans-Peter
Benutzeravatar
HeX0R
Beiträge: 2954
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: callback procedure in Exe

Beitrag von HeX0R »

Naja, als "falsch" würde ich es nicht bezeichnen, immerhin hast du von Anfang an darauf hingewiesen, dass die selbe Frage noch anderswo steht.
Aber stell Dir vor, Du bekommst Deine Anfrage in einem der Boards gelöst, siehst das aber erst nen paar Tage später, die im anderen Board wissen davon aber nichts (die deutschsprachigen lesen meist dort auch mit, umgekehrt eher selten) .
Dann gibt's dort auch jede Menge User, die sich Gedanken machen und (unnötigerweise) Zeit für Dich investieren.
Das könnte dann den einen oder anderen verärgern.

Das was Fred dort für Dich geschrieben hat, hättest Du hier auch als Antwort bekommen.

Beide Communities sind ähnlich gut aufgestellt.

Man lernt auch mit der Zeit, wo eine Frage besser platziert ist.
HPW
Beiträge: 17
Registriert: 30.08.2004 17:32

Re: callback procedure in Exe

Beitrag von HPW »

Hallo HeXOR,

Danke für die Argumente. Werde ich so halten. Wenn ich dann sofort beide Treads aktualisiere sollte es ja gehen.

Zurück zum Problem:
Anhand eines Codes ist mir etwas aufgefallen. Du hattest @mul() verwendet.

Code: Alles auswählen

Procedure CallBack1(*CallBackParam)
   theString.s = PeekS(*CallBackParam,-1,#PB_UTF8)
   MessageRequester("CallBackDemo1", "Param; "+ theString)
EndProcedure 

Procedure CallBack2()
   MessageRequester("CallBackDemo2", "NoParam")
EndProcedure 

Code: Alles auswählen

  MessageRequester("Debug", "CallBackAdress: "+ @CallBack2())
  MessageRequester("Debug", "ExeAdress: "+ @hpwNewLisp)
  newlispCallbackStr("foo", @CallBack2() ,"stdcall")
Durch Ersetzen von @CallBack2 zu @CallBack2() wird ein anderer Pointer übegeben.
Damit wird die Procedure jetzt auch gerufen und der Dialog wird angezeigt.
Aber am Ende der Procedure wirft er wieder einen Fehler.
[ERROR] Ungültiger Speicherzugriff. (Schreibfehler an der Adresse 0)
Markiert wird die Zeile EndProcedure.
Ausserdem kommt der Textparameter bei Callback1 nicht an.

Grüsse,
Hans-Peter
Hans-Peter
Benutzeravatar
HeX0R
Beiträge: 2954
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: callback procedure in Exe

Beitrag von HeX0R »

Wenn Du @Callback2() übergibst, kann Callback1 auch nicht aufgerufen werden.
Und da Deine DLL einen Parameter übergibt, ist der Stack beim ProcedureReturn korrupt.
HPW
Beiträge: 17
Registriert: 30.08.2004 17:32

Re: callback procedure in Exe

Beitrag von HPW »

Mein Fehler beim Posten.
Ich hatte mit beiden Aufrufen getestet. Auch bei Callback1 wird am Ende der Procedure der Fehler geworfen.
Das hatte ich mit "Ausserdem kommt der Textparameter bei Callback1 nicht an." gemeint.

Ich frage mich ob meine bishrige Definition des Parameters bei einem PChar mit Utf8 Inhalt richtig ist.
Und ansonsten verstehe ich Stack und ProcedureReturn im purebasic context (noch) nicht.

Grüsse,
Hans-Peter
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: callback procedure in Exe

Beitrag von mk-soft »

Purebasic hält sich an den Standards für Funktionsaufrufe und somit auch die Verarbeitung vom Stack.

Folgende fragen tun sich da auf welches format die DLL für den Callback benötigt:
- Funktion als StandardCall oder CDecl
- Anzahl der Parameter
- UTF-8 String übergabe als Pointer (Standard) oder als Pointer auf den Pointer vom dem String

Code: Alles auswählen

; Anzahl der Parameter prüfen
Procedure CallBack1(*CallBackParam)
  theString.s = PeekS(*CallBackParam,-1,#PB_UTF8)
  MessageRequester("CallBackDemo1", "Param; "+ theString)
EndProcedure

ProcedureC CallBack2(*CallBackParam)
  theString.s = PeekS(*CallBackParam,-1,#PB_UTF8)
  MessageRequester("CallBackDemo1", "Param; "+ theString)
EndProcedure

Procedure CallBack2(*CallBackParam.integer)
  theString.s = PeekS(*CallBackParam\i,-1,#PB_UTF8)
  MessageRequester("CallBackDemo1", "Param; "+ theString)
EndProcedure

ProcedureC CallBack4(*CallBackParam.integer)
  theString.s = PeekS(*CallBackParam\i,-1,#PB_UTF8)
  MessageRequester("CallBackDemo1", "Param; "+ theString)
EndProcedure

*CallbackAddr = @CallBack1()
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Antworten