Ausführen einer DLL-Funktion

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Lebostein
Beiträge: 674
Registriert: 13.09.2004 11:31
Wohnort: Erzgebirge

Ausführen einer DLL-Funktion

Beitrag von Lebostein »

Nur eine kurze Frage: CallFunctionFast() ist nur dann schneller, wenn ich die Funktionsadresse vorher und einmalig ermittle, oder? Wenn ich CallFunctionFast() in Verbindung mit IsFunction() verwende (1. Beispiel), dürfte es genauso schnell sein wie CallFunction() direkt (2. Beispiel), da ja in beiden Fällen die DLL immer wieder durchsucht wird... oder irre ich mich?

Code: Alles auswählen

Procedure MeineFunktion(param1, param2)
  FunctionID = IsFunction(#Library, "MeineFunktion")
  ProcedureReturn CallFunctionFast(FunctionID, param1, param2)
EndProcedure

Procedure MeineFunktion(param1, param2)
  ProcedureReturn CallFunction(#Library, "MeineFunktion", param1, param2)
EndProcedure
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Normalerweise nur dann, wenn du die FunktionID zwischenspeicherst. Wenn Du nicht alle FunktionID's beim öffnen der DLL ermitteln möchtest, kannst Du es auch so machen:

Code: Alles auswählen

Procedure MeineFunktion(param1, param2)
  Static FunctionID
  If FunctionID = 0 : FunctionID = IsFunction(#Library, "MeineFunktion") : EndIf
  ProcedureReturn CallFunctionFast(FunctionID, param1, param2)
EndProcedure
Nur Sinnvoll, wenn die Funktion mehrmals gebraucht wird
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
nicolaus
Moderator
Beiträge: 1175
Registriert: 11.09.2004 13:09
Kontaktdaten:

Beitrag von nicolaus »

normalerweise machst du das so das du dir für jede function der dll die du verwenden willst eine avriable anlegst.

dann rufst du bei der initialisierung deines programmes einfach alle funktionen der dll mit IsFunction() auf (natürlich erst OpenLibrary() um die dll zu öffnen) und speicherst deren speicheradresse in die angelegeten variablen.

Code: Alles auswählen

Procedure InitDLLFunctions()
  If OpenLibrary(0,"meine.dll")
    function_1 = IsFunction(0,"Function_1")
  endif
Endprocedure
na ja un nun kannst du mit deinen variablen in denen du ja jetzt die adressen der functionen deiner dll hast mit CallFanctionFast() deine funktionen aus der dll in alle proceduren deines programmes aufrufen ohne das immer wieder in der dll nach der function gesucht werden muß.

hoffe das die erklärung halbwegs verständlich war.

Gruß Nico
Benutzeravatar
Lebostein
Beiträge: 674
Registriert: 13.09.2004 11:31
Wohnort: Erzgebirge

Beitrag von Lebostein »

Danke für eure Antworten.

@ts-soft: Sehr elegante Lösung, so werd ich's machen, Danke!
traumatic
Beiträge: 478
Registriert: 27.11.2004 15:42

Beitrag von traumatic »

Lebostein hat geschrieben:@ts-soft: Sehr elegante Lösung, so werd ich's machen, Danke!
Ging es Dir nicht um Geschwindigkeit?
Dann ist der Ansatz - noch eine weitere Funktion drumherum
zu bauen - mit Erlaub keine wirklich gute Lösung.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

traumatic hat geschrieben:
Lebostein hat geschrieben:@ts-soft: Sehr elegante Lösung, so werd ich's machen, Danke!
Ging es Dir nicht um Geschwindigkeit?
Dann ist der Ansatz - noch eine weitere Funktion drumherum
zu bauen - mit Erlaub keine wirklich gute Lösung.
Du hast ja Recht, es ist auf jedenfall besser einmalig alle Funktionsadressen zu ermitteln und diese in globalen Variablen zu speichern. Da die Fehlerwahrscheinlichkeit mit vielen globalen Variablen größer wird, bietet es sich an, mit TailBite einen Wrapper zu erstellen, dann sind die globalen Variablen nur noch in der Lib global und nicht im Programm, das diese verwendet.

Meine Lösung von oben ist nur eine Notlösung, wobei ich davon ausgegangen bin, das diese If Abfrage schneller ist, als die Suche der Funktionsadresse.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
traumatic
Beiträge: 478
Registriert: 27.11.2004 15:42

Beitrag von traumatic »

Ich wollte ja auch gar nichts gegen Deine Lösung sagen, nur an
Geschwindigkeit gewinnt mal halt nicht gerade. ;)
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

traumatic hat geschrieben:Ich wollte ja auch gar nichts gegen Deine Lösung sagen, nur an
Geschwindigkeit gewinnt mal halt nicht gerade. ;)
Sollte aber schneller als diese:

Code: Alles auswählen

Procedure MeineFunktion(param1, param2)
  FunctionID = IsFunction(#Library, "MeineFunktion")
  ProcedureReturn CallFunctionFast(FunctionID, param1, param2)
EndProcedure 
sein. Habs ich aber nicht getestet. :)
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Lebostein
Beiträge: 674
Registriert: 13.09.2004 11:31
Wohnort: Erzgebirge

Beitrag von Lebostein »

Mir ging es nur darum, nicht bei jedem Funktionsaufruf die DLL zu durchsuchen bzw. wenn dann nur einmalig. Und das funktioniert ja mit dem Code ordentlich.
Benutzeravatar
nicolaus
Moderator
Beiträge: 1175
Registriert: 11.09.2004 13:09
Kontaktdaten:

Beitrag von nicolaus »

dann kannst du das auch so machen wie ich es geschrieben hatte (mach ich immer so) das du beim programmstart (initialisierung) die global angelegeten variablen mit IsFunction() "füllst" und somit im restlichen code deines programmes nur noch die variablen (in denen ja die adresse der function aus der dll steht) bei CallFunctionFast() verwenden mußt. das ist denke ich schon mal wesentlich schneller gerade wenn du ne dll mit vielen functionen hast und diese auch nutz.

gruß nico
Antworten