Re: DLL-Functionsaufruf mit Ref auf Ref
From: Erich TODT (spam.todt_at_wvnet.at)
Date: 05/27/04
- Next message: Stefan Wuebbe: "Re: DLL-Functionsaufruf mit Ref auf Ref"
- Previous message: Boas Enkler: "Re: Icons"
- In reply to: U.Husmann: "Re: DLL-Functionsaufruf mit Ref auf Ref"
- Next in thread: Stefan Wuebbe: "Re: DLL-Functionsaufruf mit Ref auf Ref"
- Reply: Stefan Wuebbe: "Re: DLL-Functionsaufruf mit Ref auf Ref"
- Reply: Jürgen Wondzinski: "Re: DLL-Functionsaufruf mit Ref auf Ref"
- Messages sorted by: [ date ] [ thread ]
Date: Thu, 27 May 2004 21:21:56 +0200
Hallo Uwe!
> int TMCOALA_EXP CoalaMakeTransportKeyVB(
> BSTR * rCertificate,
> BSTR * rPrivateKey,
> char * message,
[...]
Jupp, alles klar!
FoxPro arbeitet mit ANSI-Strings (char *), also 1 Byte pro Zeichen. Die
Länge des Strings wird gesondert gespeichert.
Ein ANSI C-String ist ein Zeiger auf jene Speicherstelle, an der das erste
Zeichen liegt, und am Ende des Strings ist eine NULL, man spricht von
"null-terminierten" Strings.
Wenn du nun mit DECLARE-DLL einen Parameter als "String" deklarierst, hängt
FoxPro automatisch die NULL hinten an und übergibt der API-Funktion einen
Zeiger (32-Bit Zahl) auf das erste Zeichen im Speicher. Wenn du einen
Parameter als "String@" deklarierst, passiert prinzipiell genau das selbe.
Der Unterschied besteht nur darin, dass die API-Funktion einmal nur auf eine
Kopie, und das andere Mal auf die Original-Daten im Speicher zugreifen kann
/ darf / soll, bzw. werden die Änderungen nach dem Funktionsaufruf in den
ursprünglichen FoxPro-String übernommen. Der 32-Bit Zeiger wird aber aus
Sicht der DLL in keinem der beiden Fälle verschoben!
Speziell für Sprachen wie Japanisch, die weit mehr als 256 Schrift-Zeichen
kennen, wurde UNICODE erfunden, das sind Strings, die wie ANSI Strings
null-terminiert sind, allerdings 2 Byte pro Zeichen erlauben.
So, und dann gibt es noch den BSTR (Binary String), der im Prinzip ein
nullterminierter UNICODE String ist, allerdings 4 Byte Vorspann hat, in
denen die Länge gespeichert wird. Und jetzt kommt's: Zur Kompatibilität
zeigt BSTR (definiert als OLECHAR*) auf das erste Zeichen eines
UNICODE-Strings, und die 4 Längenbytes sind VOR dem Pointer im Speicher. Man
sollte allerdings nicht direkt auf die Längenbytes zugreifen, sondern die
Funktion SysStringLen() in OLEAUT32.DLL verwenden, um die Länge zu erfragen.
Damit kann man den String entweder bis zur ersten NULL absuchen wie einen
UNICODE String, oder man verwendet SysStringLen() und liest die
entsprechenden Zeichen aus, wobei dann natürlich auch NULLen dabei sein
dürfen.
Siehe Doku im Platform-SDK:
http://msdn.microsoft.com/library/en-us/automat/htm/chap7_2xgz.asp?frame=true
Um nun einen bestehenden UNICODE-String in eine BSTR umzuwandeln, muss man
also VOR dem eigentlichen String noch die Längenbytes unterbringen. Das
bewerkstelligt die Funktion SysAllocString(), ebenfalls in OEAUT32.DLL, die
eine Kopie des UNICODE-Strings (samt Nullterminierung) erstellt, davor die
Längenbytes platziert und schließlich einen 32-Bit Pointer auf das erste
UNICODE-Zeichen zurückgibt.
Der mit SysAllocString() reservierte Speicher muss mit SysFreeString()
wieder freigegeben werden.
Um zwischen den ANSI- und UNICODE Strings zu konvertieren, benutzt man im
Allgemeinen die API-Funktionen
MultiByteToWideChar() und
WideCharToMultiByte().
Ich habe eine Mini-DLL geschrieben, die eine einzige Funktion enthält,
welche genau einen Pointer auf einen BSTR erwartet.
Das dürfte wohl deiner DLL recht nahe kommen.
Meine Funktion gibt den empfangenen BSTR in einer MessageBox aus und setzt
ihn neu mit SysReAllocString().
Bei der Umwandung von ANSI auf UNICODE gehe ich der Einfachheit halber von
einem String ohne NULLen aus.
Hier kannst du mein FoxPro-Beispiel und die DLL samt Quellcode herunterladen
http://www.todt.at/erich/download/samples/foxpro/bstr/fox_bstr_demo.zip
Verwendeter Trick:
Da der BSTR-Parameter ein 32-Zeiger (eine Zahl !!!) auf den UNICODE-String
in einem BSTR ist, deklariere ich den entsprechenden Parameter "bstr" als
Integer.
Der Funktion WideCharToMultiByte ist es egal, ob sie den Pointer auf den
UNICODE-String (lpWideCharString) von FoxPro vorgesetzt bekommt, oder ob
gleich ein Integer übergeben wird. Bleibt g'hupft wie g'hatscht <g>
Für deine DLL bleibt nun noch abzuklären, ob sie beim Aufruf bereits einen
Pointer auf einen gültigen BSTR erwartet, oder ob du auch 0 übergeben
darfst. Umgekeht solltest du (ggf beim Hersteller) erfragen, ob Du nach dem
Aufruf für das Freigeben mit SysFreeString() verantwortlich bist, oder ob
dir das irgend eine interne Routine z.B. beim Freigeben der DLL (CLEAR DLLS
oder Programm-Ende) abnimmt...
Ich hoffe, das hilft dir weiter!
Erich
--- Erich TODT dFPUG Regionalleiter Wien URL: http://www.todt.at/
- Next message: Stefan Wuebbe: "Re: DLL-Functionsaufruf mit Ref auf Ref"
- Previous message: Boas Enkler: "Re: Icons"
- In reply to: U.Husmann: "Re: DLL-Functionsaufruf mit Ref auf Ref"
- Next in thread: Stefan Wuebbe: "Re: DLL-Functionsaufruf mit Ref auf Ref"
- Reply: Stefan Wuebbe: "Re: DLL-Functionsaufruf mit Ref auf Ref"
- Reply: Jürgen Wondzinski: "Re: DLL-Functionsaufruf mit Ref auf Ref"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|