Seite 1 von 1

Mehrere Rückgabewerte aus einer Library (DLL) beziehen

Verfasst: 30.03.2013 11:08
von Micha122
Hallo,
ich möchte einige meiner Prozeduren als Library verwenden.
Die Prozeduren in meinem Code sind alle nach folgendem Schema aufgebaut:

Code: Alles auswählen

Structure Datensatz
  herausgeber_und_info.s
  Datum.s
  Waehrung.s
  EndStructure

Procedure Datensatz_einlesen(file.s, *Datensatz.Datensatz)
  *Datensatz\herausgeber_und_info.s = "Firma Muster"
  *Datensatz\Datum.s = "16.02.03"
  *Datensatz\Waehrung.s = "EUR" 
EndProcedure

Define Datensatz.Datensatz
Datensatz_einlesen(file.s, @Datensatz)
Debug Datensatz\herausgeber_und_info
Debug Datensatz\Datum
Debug Datensatz\Waehrung
Wie müsste die dll aussehen anhand des Code- Beispiels?
Wie müsste ich die dll aufrufen?

Grüße, Michael

Re: Mehrere Rückgabewerte aus einer Library (DLL) beziehen

Verfasst: 30.03.2013 11:14
von mk-soft
Die Basis ist schon Richtig.

Nur noch "Procedure" in ProcedureDLL umschreiben und aus der Hilfe "Erstellung einer DLL" das Grundgerüst übernehmen.

P.S. Als Rückgabewert würde ich immer den Erfolg der Procedure ausgeben, z.B. Anzahl der bearbeitenden Datensätze.

Re: Mehrere Rückgabewerte aus einer Library (DLL) beziehen

Verfasst: 30.03.2013 12:29
von Micha122
@mk-soft

Angenommen die dll würde so aussehen:

Code: Alles auswählen

Structure Datensatz
  herausgeber_und_info.s
  Datum.s
  Waehrung.s
  EndStructure

ProcedureDll Datensatz_einlesen(file.s, *Datensatz.Datensatz)
  *Datensatz\herausgeber_und_info.s = "Firma Muster"
  *Datensatz\Datum.s = "16.02.03"
  *Datensatz\Waehrung.s = "EUR" 
EndProcedure
Wie kommt der Client also das Hauptprogramm dann an die Struktur "Datensatz"?
Die Struktur ist ja im Hauptprogramm nicht bekannt.

Re: Mehrere Rückgabewerte aus einer Library (DLL) beziehen

Verfasst: 30.03.2013 12:54
von mk-soft
Die Struktur muss IMMER auch im Hauptprogramm bekannt sein.
Darum liefert ja auch PB für die WinAPI die Strukturen auch mit.

P.S. Achtung!!! Ist noch ein Fehler in der Struktur. So kann man nicht mit String arbeiten.
Bastel das mal richtig hin... Moment...

Re: Mehrere Rückgabewerte aus einer Library (DLL) beziehen

Verfasst: 30.03.2013 13:11
von mk-soft
String in einer Struktur bei übergabe in einer DLL müssen eine statische Grösse haben. Einfache Strings ist nur der Pointer auf den String und werden aus der DLL nicht richtig behandelt.

Code: Alles auswählen

Structure Datensatz
  herausgeber_und_info.s{32}
  Datum.s{8}
  Waehrung.s{4}
  EndStructure

ProcedureDLL Datensatz_einlesen(file.s, *Datensatz.Datensatz)
  *Datensatz\herausgeber_und_info.s = "Firma Muster"
  *Datensatz\Datum.s = "16.02.03"
  *Datensatz\Waehrung.s = "EUR"
EndProcedure

;-Test

Define ds.Datensatz
; da ds eine Struktur ist wird immer der Zeiger auf die Struktur übergeben
Datensatz_einlesen("", ds)

With ds
  Debug \herausgeber_und_info
  Debug \Datum
  Debug \Waehrung
EndWith

Re: Mehrere Rückgabewerte aus einer Library (DLL) beziehen

Verfasst: 30.03.2013 16:58
von Micha122
@mk-soft
So wie Dein Code da steht funktioniert er auch, allerdings nicht wenn die Procedure abseits vom Hauptprogramm eine dll ist.

Vielleicht haben wir aber auch nur aneinander vorbei geredet?

Folgendes z.B. funktioniert tadellos, gefällt mir aber nicht:

Eine dll namens aa.dll

Code: Alles auswählen

Global rueckstring.s

ProcedureDLL.s test()
  a.s="aaaaaaa"
  b.s="bbbbbbb"
  rueckstring.s=a.s+";"+b.s
  ProcedureReturn rueckstring.s
  
  EndProcedure
Wie Du siehst bastle ich einfach aus 2 Strings einen String als Rückgabewert. Als Trennzeichen verwende ich ";".

Dieses Hauptprogramm benutzt die dll:

Code: Alles auswählen

If OpenLibrary(0,"aa.dll")
  Rueckstring.s = PeekS(CallFunction(0, "test"))
  Debug StringField(Rueckstring.s,1,";")
    Debug StringField(Rueckstring.s,2,";")
EndIf
Diese Methode funktioniert, ich finde sie lediglich nicht sehr elegant.

Ich würde viel lieber im Hauptprogramm eine Struktur anlegen und diese dann in der dll benutzen, falls das überhaupt machbar ist??

Re: Mehrere Rückgabewerte aus einer Library (DLL) beziehen

Verfasst: 31.03.2013 13:17
von mk-soft
Hier mal Vollständig...

Einmal als TestDLL.dll compilieren und dann normal mit Debugger ausführen. Bei mir geht es so wie es soll.

Code: Alles auswählen

;TOP

; File "TestDLL.dll"

; Struktur muss in der DLL und im Hauptprogramm bekannt sein

Structure Datensatz
  herausgeber_und_info.s{32}
  Datum.s{8}
  Waehrung.s{4}
EndStructure

CompilerIf #PB_Compiler_ExecutableFormat = #PB_Compiler_DLL

ProcedureDLL Datensatz_einlesen(file.s, *Datensatz.Datensatz)
  *Datensatz\herausgeber_und_info.s = "Firma Muster"
  *Datensatz\Datum.s = "16.02.03"
  *Datensatz\Waehrung.s = "EUR"
EndProcedure

CompilerEndIf

;-Test

CompilerIf #PB_Compiler_ExecutableFormat = #PB_Compiler_Executable
  
  Prototype ProtoDatensatz_einlesen(file.s, *Datensatz.Datensatz)
  If OpenLibrary(0, "TestDLL.dll")
    Datensatz_einlesen.ProtoDatensatz_einlesen = GetFunction(0, "Datensatz_einlesen")
  Else
    End
  EndIf
  
  Define ds.Datensatz
  ; da ds eine Struktur ist wird immer der Zeiger auf die Struktur übergeben
  Datensatz_einlesen("", ds)
  
  With ds
    Debug \herausgeber_und_info
    Debug \Datum
    Debug \Waehrung
  EndWith
  
CompilerEndIf
P.S. Compiler-Option richtig eingestellt? (Rechts neben den Start-Button)

Re: Mehrere Rückgabewerte aus einer Library (DLL) beziehen

Verfasst: 31.03.2013 15:27
von Micha122
Hallo und erstmal frohe Ostern!

Danke, funktioniert prima und ist genau das was ich gesucht habe. :allright:

Ich habe den Fehler gemacht und die Structure entweder nur im Hauptprogramm oder nur in der dll geschrieben. :oops:

Trotzdem immer wieder erstaunlich wieviele möglichkeiten es in PB gibt um sein Ziel zu erreichen. :D

Grüße, Michael