DllCall() und String als Rückgabe [erledigt]
Moderator: Moderatoren
- Werner_Bayern
- Der Entwickler von "Deep Thought"
- Beiträge: 2126
- Registriert: Sa, 30. Jan 2010 22:58
- Wohnort: Niederbayern
- Hat sich bedankt: 30 Mal
- Danksagung erhalten: 75 Mal
DllCall() und String als Rückgabe [erledigt]
Servus,
mache gerade die ersten Gehversuche mit einer C-DLL, funktioniert so bisher alles, jedoch liefert ja DllCall() immer einen numerischen Rückgabewert. Was macht man, wenn man aber einen String zurückbekommt?
Geht das mit Bordmittel oder brauche ich dazu die otx4b.dll und ReadStr()?
mache gerade die ersten Gehversuche mit einer C-DLL, funktioniert so bisher alles, jedoch liefert ja DllCall() immer einen numerischen Rückgabewert. Was macht man, wenn man aber einen String zurückbekommt?
Geht das mit Bordmittel oder brauche ich dazu die otx4b.dll und ReadStr()?
Zuletzt geändert von Werner_Bayern am Mo, 12. Nov 2012 22:54, insgesamt 1-mal geändert.
es grüßt
Werner
<when the music is over, turn off the lights!>
Werner
<when the music is over, turn off the lights!>
- brandelh
- Foren-Moderator
- Beiträge: 15697
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Re: DllCall() und String als Rückgabe
Hallo,
das kommt auf den Rückgabewert der C-DLL an.
dllcall() gibt bei Fremd-DLL immer einen numerischen Wert zurück.
Dies könnte ein Pointer auf einen ASCIIZ String sein ( char* in C ).
Oft wird aber nur der Erfolg ( meist 0 OK, Rest Fehlermeldung, oder 0 Fehler, sonst Handle) bzw. Handles zurückgegeben
und Werte über die Parameter (so kann man Strings zurückbekommen mit pur Xbase++), wenn nicht, hilft (nur) die ot4xb.
Bei der QuickPDF habe ich Funktionen für die Behandlung von String (Pointer) Rückgabewerten von Pablo abgekupfert :
das kommt auf den Rückgabewert der C-DLL an.
dllcall() gibt bei Fremd-DLL immer einen numerischen Wert zurück.
Dies könnte ein Pointer auf einen ASCIIZ String sein ( char* in C ).
Oft wird aber nur der Erfolg ( meist 0 OK, Rest Fehlermeldung, oder 0 Fehler, sonst Handle) bzw. Handles zurückgegeben
und Werte über die Parameter (so kann man Strings zurückbekommen mit pur Xbase++), wenn nicht, hilft (nur) die ot4xb.
Bei der QuickPDF habe ich Funktionen für die Behandlung von String (Pointer) Rückgabewerten von Pablo abgekupfert :
Code: Alles auswählen
METHOD HBPrintPDF:GetDefaultPrinterName()
return ::ReadString(::_str_result_(FpQCall( {::_hdll_,"QuickPDFGetDefaultPrinterNameA"} ,"__pt__sl",::_id_)))
INLINE METHOD ReadString( cString ) // The DLL needs ANSI Parameters, if not UTF8 !
DEFAULT cString TO ""
if ::UseAutoConvUTF8 // string parameter == ANSI/OEM
if ::nCharSet = 1 // ANSI => OEM
cString := ConvToOemCP(cString)
endif // OK OEM
else
// wenn ! ::UseAutoConvUTF8, erhält man UTF8, verwenden mit z.b. ReadUTF8()
// return value is UTF8, use it !
endif
Return cString
INLINE METHOD _str_result_(p)
local cb
if Empty(p) ; RETURN "" ; end
cb := ::StringResultLength() // maximale Stirnglänge bei der Bibliothek, sollte in Doku stehen.
return PeekStr(p,0,cb) // ASCIIZ Strings, was zu lange ist wird hinter dem Stringendezeichen ( chr(0) ) abgeschnitten
Gruß
Hubert
Hubert
- Werner_Bayern
- Der Entwickler von "Deep Thought"
- Beiträge: 2126
- Registriert: Sa, 30. Jan 2010 22:58
- Wohnort: Niederbayern
- Hat sich bedankt: 30 Mal
- Danksagung erhalten: 75 Mal
Re: DllCall() und String als Rückgabe
Servus Hubert,
danke, so hab ich es jetzt inzwischen auch gemacht:
scheint zu funktionieren.
danke, so hab ich es jetzt inzwischen auch gemacht:
Code: Alles auswählen
local nPointer := dllcall("C-lib.dll", DLL_CDECL, "libFunctionsName", nParameter1)
return Peekstr(nPointer, 0, -1)
es grüßt
Werner
<when the music is over, turn off the lights!>
Werner
<when the music is over, turn off the lights!>
- brandelh
- Foren-Moderator
- Beiträge: 15697
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Re: DllCall() und String als Rückgabe
Hallo Werner,
ich weiß nicht, was passiert wenn der Rückgabewert NIL oder 0 ist und ob das überhaupt vorkommen kann,
aber wenn Pablo diese Zeile als Schutz eingebaut hat, würde ich das auch tun
Außerdem musste ICH feststellen, dass eine fehlende DLL die man so aufruft eine sehr seltsame Fehlermeldung bringt, ich würde also DllLoad() nutzen.
Wenn du zusätzlich noch dllcall gegen Pablos nFpCall() tauschst, brauchst du dir um STDCALL and CDECL keine Gedanken manchen.
Aus der QuickPDF habe ich eine Klasse gemacht, da ich die DLL nur einmal öffnen muss und interne Variablen halten kann.
DllUnload() führe bei der QuickPDF zu einem Speicherloch (diese gab den Speicher intern nicht frei), aber eigentlich
dürfte es kein Problem sein die DLL einfach offen zu halten, der zweite Aufruf lädt sie nicht neu, eventuell nutzt er aber ein neues Handle.
Pablo hat noch eine interessante Kurzschreibweise und die obige Parameter Erklärung hier:
http://www.xbwin.com/ot4xbXHlp/
=> Tutorial => The ot4xb nFpCall() function
ich weiß nicht, was passiert wenn der Rückgabewert NIL oder 0 ist und ob das überhaupt vorkommen kann,
aber wenn Pablo diese Zeile als Schutz eingebaut hat, würde ich das auch tun
Code: Alles auswählen
if Empty(p) ; RETURN "" ; end
Wenn du zusätzlich noch dllcall gegen Pablos nFpCall() tauschst, brauchst du dir um STDCALL and CDECL keine Gedanken manchen.
Code: Alles auswählen
function MyStringFunc(nParameter1)
local nDll, nPointer, cReturn := ""
nDll := DllLoad("C-lib.dll")
if empty(nDll)
msgbox("DLL konnte nicht geladen werden, fehlt sie ?")
else
nPointer := nFpCall( { nDLL, "libFunctionsName" }, nParameter1, ... ) //
if ! empty(nParameter1)
cReturn := Peekstr(nPointer, 0, -1)
endif
// DllUnLoad(nDLL)
endif
return
DllUnload() führe bei der QuickPDF zu einem Speicherloch (diese gab den Speicher intern nicht frei), aber eigentlich
dürfte es kein Problem sein die DLL einfach offen zu halten, der zweite Aufruf lädt sie nicht neu, eventuell nutzt er aber ein neues Handle.
Pablo hat noch eine interessante Kurzschreibweise und die obige Parameter Erklärung hier:
http://www.xbwin.com/ot4xbXHlp/
=> Tutorial => The ot4xb nFpCall() function
Gruß
Hubert
Hubert
- Werner_Bayern
- Der Entwickler von "Deep Thought"
- Beiträge: 2126
- Registriert: Sa, 30. Jan 2010 22:58
- Wohnort: Niederbayern
- Hat sich bedankt: 30 Mal
- Danksagung erhalten: 75 Mal
Re: DllCall() und String als Rückgabe
Danke, auf die Funktion von Pablo war ich auch schon gestoßen, denke aber, dass es so schneller (wenn auch nicht komfortabler) geht.
Das mit dem Rückgabewert werde ich mit einbauen, guter Hinweis.
Ja, auch mein Kenntnisstand ist, dass dllload die DLL nur 1x in den Speicher lädt. Deshalb verzichte ich bewusst auf die ständigen Aufrufe von dllLoad und dllUnload.
Das mit dem Rückgabewert werde ich mit einbauen, guter Hinweis.
Ja, auch mein Kenntnisstand ist, dass dllload die DLL nur 1x in den Speicher lädt. Deshalb verzichte ich bewusst auf die ständigen Aufrufe von dllLoad und dllUnload.
es grüßt
Werner
<when the music is over, turn off the lights!>
Werner
<when the music is over, turn off the lights!>
- brandelh
- Foren-Moderator
- Beiträge: 15697
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Re: DllCall() und String als Rückgabe
wenn du SCHREIBEN von Quellcode meinst, hast du sicher recht.Werner_Bayern hat geschrieben:Danke, auf die Funktion von Pablo war ich auch schon gestoßen, denke aber, dass es so schneller (wenn auch nicht komfortabler) geht.
Bei der Ausführung, dürften beide gleich schnell sein, die Sicherheitsabfragen fallen nicht ins Gewicht.
Außerdem, DLLFUNCTION ... wird vom Präprozessor in mehrere Funktionaaufrufe aufgeteilt
Gruß
Hubert
Hubert
- Werner_Bayern
- Der Entwickler von "Deep Thought"
- Beiträge: 2126
- Registriert: Sa, 30. Jan 2010 22:58
- Wohnort: Niederbayern
- Hat sich bedankt: 30 Mal
- Danksagung erhalten: 75 Mal
Re: DllCall() und String als Rückgabe
Nein, ich nutze doch dllCall().
Aber Du hast Recht, ich hab testweise Mal nFpCall anstatt dllCall() verwendet, konnte aber keine erkennbaren Unterschiede feststellen. Bei sowas bleibe ich dann lieber bei den Xbase++-Funktionen. Den Typus kenne ich und die zu übergebenden Variablen konvertiere ich bei Bedarf lieber selbst.
Der Syntax von nFpCall ist übrigens in der Hilfe falsch beschrieben. Die ersten beiden Parameter müssen als Array übergeben werden.
Aber Du hast Recht, ich hab testweise Mal nFpCall anstatt dllCall() verwendet, konnte aber keine erkennbaren Unterschiede feststellen. Bei sowas bleibe ich dann lieber bei den Xbase++-Funktionen. Den Typus kenne ich und die zu übergebenden Variablen konvertiere ich bei Bedarf lieber selbst.
Der Syntax von nFpCall ist übrigens in der Hilfe falsch beschrieben. Die ersten beiden Parameter müssen als Array übergeben werden.
es grüßt
Werner
<when the music is over, turn off the lights!>
Werner
<when the music is over, turn off the lights!>
- brandelh
- Foren-Moderator
- Beiträge: 15697
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Re: DllCall() und String als Rückgabe
unter Funktionen fehlt die Option, dass man es AUCH als Array übergeben kann, mein Link zeigt auf das Tutorial wo es erwähnt wird.Werner_Bayern hat geschrieben:Der Syntax von nFpCall ist übrigens in der Hilfe falsch beschrieben.
Die ersten beiden Parameter müssen als Array übergeben werden.
nFpCall() ist da sehr flexibel, ich selbst nutzte aber die Funktion (siehe Quellcode oben) in der die Typen übergeben werden.
PS: hauptsache es geht
Gruß
Hubert
Hubert