Seite 1 von 1

String (Konstante) als Rückgabewert aus DLL

Verfasst: 16.03.2014 13:00
von Chimorin
Heyho,

Ich würde gerne meine DLL um ein paar Funktionen erweitern, welche Strings als Rückgabewert beinhalten.
Jedoch erhalte ich Unicodeunsinn (Glaube ich zumindest). Für ein einfaches "B" als Rückgabewert erhalte ich dies:
In der Dokumentation steht das hier:
Hinweise zur Rückgabe von Strings aus DLL's:

Bei der Rückgabe von Strings aus einer DLL-Funktion muß der String als Global deklariert sein.
Das hilft mir aber nicht wirklich weiter.

Doch wie bekomme ich mein "B" als Rückgabewert?

Code: Alles auswählen

ProcedureDLL.s TasteZuText(taste.i)        ;Übersetzt den Wert einer Taste in einen anzeigbaren String.
  Select taste
      
    Case #Key_B
      ProcedureReturn "B"
      
      ;...
      
  EndSelect
EndProcedure
Die Funktion inkludiere ich über Prototypes, in etwa so:

Code: Alles auswählen

Prototype.s ProtoTasteZuText(taste.i)
Global.ProtoTasteZuText TasteZuText

OpenLibrary(#spielDLL, "SpielDLL (x64).dll")
TasteZuText = GetFunction(#spielDLL, "TasteZuText")
Debug TasteZuText(#Key_B)
Ist es einfach möglich, an das "B" zu kommen? Sollte das nicht einfach möglich sein, mache ich mir einfach eine .pb-Datei, die dann eben von allen Programmen inkludiert werden muss...

Re: String (Konstante) als Rückgabewert aus DLL

Verfasst: 16.03.2014 13:21
von Sicro
Chimorin hat geschrieben:In der Dokumentation steht das hier:
Hinweise zur Rückgabe von Strings aus DLL's:

Bei der Rückgabe von Strings aus einer DLL-Funktion muß der String als Global deklariert sein.
Das hilft mir aber nicht wirklich weiter.
Nach diesem Text wird in der Hilfe noch ein Beispiel und weitere Informationen geliefert, jedenfalls bei der Hilfe von PureBasic 5.21. Bitte weiterlesen.

Du musst den String vorher in eine globale Variable speichern und diese als Rückgabe bei der Procedure verwenden.

Re: String (Konstante) als Rückgabewert aus DLL

Verfasst: 16.03.2014 13:36
von Andreas21
Du darfst Peek aber auch nicht vergessen, da die DLL nur einen Pointer auf den String dir zurück gibt.
Mit Prototype.s geht es nicht.

z.b.

Code: Alles auswählen

Prototype ProtoTasteZuText(taste.i)
Global.ProtoTasteZuText TasteZuText

OpenLibrary(#spielDLL, "SpielDLL (x64).dll")
TasteZuText = GetFunction(#spielDLL, "TasteZuText")
Debug PeekS(TasteZuText(#Key_B))
oder

Code: Alles auswählen

Prototype ProtoTasteZuText(taste.i)
Global.ProtoTasteZuText TasteZuText

Macro TasteZuText_(Taste)
    PeekS(TasteZuText(Taste))
EndMacro

OpenLibrary(#spielDLL, "SpielDLL (x64).dll")
TasteZuText = GetFunction(#spielDLL, "TasteZuText")
Debug TasteZuText_(#Key_B)
Anstelle einer Globalen Variable könntest du aber auch eine Static in der Procedure nutzen.
Find ich persönlich besser als Globale Variablen.

Code: Alles auswählen

ProcedureDLL.s TasteZuText(taste.i)        ;Übersetzt den Wert einer Taste in einen anzeigbaren String.
  Static Return$
  Return$ = ""
  Select taste
      
    Case #Key_B
      Return$ = "B"
      
      ;...
      
  EndSelect
  ProcedureReturn Return$
EndProcedure

Re: String (Konstante) als Rückgabewert aus DLL

Verfasst: 16.03.2014 18:28
von Chimorin
Aha, danke für die Hilfe. Ich weiß nicht, die Dokumentationseite sah heute Mittag anders aus (Meine ich zumindest :D).
Eventuell habe ich auch einfach nur eine andere Seite gelesen, die nur einen Teil der Infos enthält.

Ein PeekS() hat die Sache gelöst, Danke :)

Nur noch eine Frage: Es wird doch die Speicheradresse zurückgegeben; Warum gibt Debug dann diese merkwürdigen Zeichen aus und keine Zahlenreihe?!

Re: String (Konstante) als Rückgabewert aus DLL

Verfasst: 23.03.2014 01:55
von _sivizius
weil der Debugger bei sehr speziellen Dingen ziemlich komisch ist.
Ob ein Pointer auf einen String oder ein String zurückgegeben wird ist nur eine Sache der Verarbeitung, an sich ist es das selbe. Der Debugger wird also sicherlich schon von einem String ausgehen, weil du die Procedure als .s deklariert hast...könnten vll. Pseudotypen helfen?
Es könnte sein, das weiß ich nicht, dass der Speicherplatz für den String bei der ProcedureDLL für "B" freigegeben wird, weswegen man ja Global oder besser Shared benutzen soll. Du ließt möglicherweise in nem fremden Speicher rum, der bereits anders genutzt wird(?).
Vielleicht gibt ja eine asm-Ausgabe mehr Auskunft. Ansonsten halt Shared oder du hast eine geeignete Struktur, mit der du deine eigenen Strings verwaltest.