Hallo,
Dank für die Hilfen. Falls jemand auch 'mal eine Lösung dafür benötigt, dass ein rufendes Fremdprogramm einen String übergibt, dessen Wert in der DLL abgeändert werden muss.
Code: Alles auswählen
ProcedureDLL.i setstring(query.s, PString.l,maxlen.i)
;PString ist ein Pointer, der von externem Programm auf eine
;dort def. Stringvariable (per var-Deklaration im Aufruf) verweist,
;für die eine Länge von maxlen Zeichen vorbelegt ist.
;In dieser Prozedur wird 'Inhalt' aus 'query' berechnet und über den Pointer
; an das rufende Windowsprogramm zurückgereicht.
Protected res.i,Membedarf.i,Inhalt.s
res.i=0
; Zur Demo eine primitive Wertzuweisung an 'Inhalt' (ohne Nutzung von 'query')
Inhalt="Dieser Text wird in der DLL erzeugt"
Membedarf.i=Len(Inhalt)
If Membedarf<=maxlen
CopyMemoryString(Inhalt,@PString)
res=1
Else
MessageRequester("Zu wenig Speicher","reserviert:"+Str(maxlen)+"Byte"+Chr(13)+Chr(10)+"benötigt:"+Str(Membedarf)+"Byte")
EndIf
ProcedureReturn res
EndProcedure
Damit ist man doch wohl in jedem Fall vor Überschreibproblemen im Speicher geschützt, oder?
Das funktioniert so prima, wenngleich ein Problem bleibt:
Wie übermittele ich dem rufenden Fremdprogramm den erforderlichen Wert von 'maxlen'? Man will ja nicht eine Annäherung an einen sinnvollen Wert durch Probieren erreichen.
Macht es Sinn, Inhalt als für die DLL global zu definieren und dann die Berechnung von Inhalt in eine Prozedur useMem zu verlagern, die zunächst aufgerufen wird. Also etwa so:
Code: Alles auswählen
global Inhalt
ProcedureDLL.i setstring(PString.l,maxlen.i)
Protected res.i,Membedarf.i
res.i=0
Membedarf.i=Len(Inhalt)
If Membedarf<=maxlen
CopyMemoryString(Inhalt,@PString)
res=1
Else
MessageRequester("Zu wenig Speicher","reserviert:"+Str(maxlen)+"Byte"+Chr(13)+Chr(10)+"benötigt:"+Str(Membedarf)+"Byte")
EndIf
ProcedureReturn res
EndProcedure
ProcedureDLL.i useMem(query.s)
;Demo Werzuweisung an Inhalt, der anhand der query berechnet wird
Inhalt="Dieser Text wird in der DLL erzeugt"
ProcedureReturn len(Inhalt)
EndProcedure
Dann aber müsste der Aufruf der DLL so erfolgen:
1) usemem berechnet Inhalt und reicht den erforderlichen Speicherplatz (=maxlen) zurück ans Fremdprogramm
2) Das Fremdprogramm belegt die Stringvariable mit maxlen Zeichen vor.
3) Das Fremdprogramm ruft setstring auf.
Hat jemand eine bessere Idee? Denn hier müsste ja die Aufrufreihenfolge strikt eingehalten werden!
Dank vorab!