DLLs und Strings, PeekS und Global

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7039
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

DLLs und Strings, PeekS und Global

Beitrag von STARGÅTE »

Tachchen,

derzeit stehe ich vor einem kleinen Problem bezüglich DLLs und Strings.
Laut Hilfe muss ein String, welcher aus der DLL zurückgegeben wird, global sein,
damit er nach dem Verlassen der DLL-Prozedur noch verfügbar ist. (klar)
Dieser muss dann zusätzlich mit PeekS() gelesen werden, da es nur ein Pointer zurückgegeben wird. (klar)

Scheinbar funktioniert das Übergeben von String an die DLL "alleine" also ohne PeekS in der DLL-Prozedur (hmm).

Nun habe ich aber ein Problem wenn der "Weg" nicht nur PB -> DLL-Prozedur -> PB ist, sondern wie im folgenden Beispiel:
PB -> DLL-Prozedur -> PB-Prozedur -> DLL-Prozedur -> PB

Mit anderen Worten, ich möchte eine DLL-Prozedur aufrufen welche selbst eine übergebene PB-Prozedur ausführen soll.

Evaluate.pb für die Erstellung der Evaluate.dll (Evaluate.lib):

Code: Alles auswählen

Prototype.s Function(Parameter.s)

Global Result.s

ProcedureDLL.s Evaluate(Function.Function, Parameter.s)
  Result = "++ " + Function(Parameter) + " ++"
  ProcedureReturn Result
EndProcedure
Example.pb zum nutzen der Evaluate.dll

Code: Alles auswählen

Import "Evaluate.lib"
  Evaluate(*Function, Parameter.s)
EndImport

Procedure.s Test(Parameter.s)
  ProcedureReturn "-- " + Parameter + " --"
EndProcedure

Debug PeekS(Evaluate(@Test(), "Hallo Welt!"))
Theoretisch sollte ich nun "++ -- Hallo Welt! -- ++" bekomme, jedoch bekomme ich nur:
"++ ++", also das Resultat aus der DLL aber ohne den Inhalt von der PB-Prozedur.

Ansatz wäre nun:
Ich muss auch ein PeekS() in der DLL machen, damit ich Strings von PB bekomme, aber wieso brauch ich das dann nicht bei Parametern im allgemeinen ? (unklar)

Neue Evaluate.pb wäre also:

Code: Alles auswählen

Prototype.i Function(Parameter.s)

Global Result.s

ProcedureDLL.s Evaluate(Function.Function, Parameter.s)
  Result = "++ " + PeekS(Function(Parameter)) + " ++"
  ProcedureReturn Result
EndProcedure
Nur muss ich dann auch in PB die Rückgabe-Strings immer global machen, damit die DLL darauf zugreifen kann?
Denn die Example.pb funktioniert auch ohne weitere Änderungen. (unklar)

Vielleicht kann mir jemand etwas mehr Licht in die Sache bringen, wann ich ein String-Result global machen muss und mit PeekS lesen muss.
Immer wenn es von DLL->PB oder PB->DLL geht?
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
mk-soft
Beiträge: 3902
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: DLLs und Strings, PeekS und Global

Beitrag von mk-soft »

Die DLL läuft in einer eigenen Speichergebiet. Läuft also nicht mit der Standardfunktion für Procedurerückgabe als String.
Also immer den Zeiger auf ein String Arbeiten. Ist aber somit nicht Threadsafe. Am besten wie bei API den Rückgabestring als Parameter als *pszText umsetzen.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7039
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: DLLs und Strings, PeekS und Global

Beitrag von STARGÅTE »

Ja schon, aber scheinbar muss ich das auch in die andere Richtung machen?
Wenn also eine Funktion in PB einen String zur DLL zurück gibt?
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Velox
Beiträge: 39
Registriert: 18.09.2011 18:02

Re: DLLs und Strings, PeekS und Global

Beitrag von Velox »

Moin,

arbeite schon seit längerer Zeit mit DLLs und ich nutze wenn dann meistens "Global Var erhält Informationen (Integer und auch String )aus DLL".
Damit konnte ich bisher immer gut arbeiten.
Neben Integer und Strings habe ich auch Bilder verwendet als IncludeBinary, mag für manche etwas komisch vorkommen.

Wenn es Dir nur darum geht Informationen als Integer oder String aus der DLL zu lesen, dann hier etwas was bei mir funktioniert hat:

====================

Prototype FileTheme(Param1)
Info.FileTheme = GetFunction(#File_Theme,"InfoAboutTheme")
Theme_Name$ = PeekS(Info(0))

====================

Dadurch das Theme_Name$ bereits als Global gemacht wurde, kann ich mit Theme_Name$ überall aus jeder DLL die die exakten Variablen inne hat, darauf zurückgreifen und auch während der Laufzeit.
Demnach ich musste die Anwendung nicht neustarten oder sowas und konnte dennoch verschiedene DLLs mit dem selben Inhalt jedoch verschiedenen Werten, nutzen.

Denke das meiste gehört in die Anfänger-Spate dieses PB-Board, aber evtl. bringe ich Dich damit auf irgendeinen Gedanken der Dich weiter voran bringt.


Grüße
Velox

//Nachtrag:

In deinem Beispiel globalisierst Du Result, das ist doch wenn ich mich jetzt nicht irre falsch?!
Du musst das eigentliche Ergebnis/den eigentlichen Wert globalisieren damit Du auch ++ --Hallo Welt-- ++ heraus bekommst. ;)
Antworten