![]() |
Leerstring bei Interface
In einem Projekt mache ich ausgiebig Gebrauch von dem Itunes COM Interface, um von meinem Programm aus die Itunes-Software 'fernsteuern' zu können. Das funktioniert i. d. R. problemlos. Laut der 'iTunes COM Interface Documentation' sind Strings als 'BSTR' deklariert, die ja mit dem 'Widestring' von Delphi kompatibel sind. Das Auslesen dieser Strings ist kein Problem, eine Zuweisung zu einem solchen String normalerweise auch nicht. Nur wenn ich einen solchen String 'löschen' will, indem ich einen Leerstring zuweise, gibt es eine Delphi-Exception 'EOleException Ungültiger Zeiger'.
In der Typelibrary 'iTunesLib_TLB' ist z. B. der String 'EpisodeID' folgendermaßen deklariert:
Delphi-Quellcode:
Bisher habe ich mich damit beholfen, dass ich anstatt eines Leerstrings (EpisodeID := '') einen Nullwert übergebe (EpisodeID := #0).
// *********************************************************************//
// Interface: IITFileOrCDTrack // Flags: (4432) Hidden Dual OleAutomation Dispatchable // GUID: {00D7FE99-7868-4CC7-AD9E-ACFD70D09566} // *********************************************************************// IITFileOrCDTrack = interface(IITTrack) ['{00D7FE99-7868-4CC7-AD9E-ACFD70D09566}'] [...] function Get_EpisodeID: WideString; safecall; procedure Set_EpisodeID(const EpisodeID: WideString); safecall; [...] property EpisodeID: WideString read Get_EpisodeID write Set_EpisodeID; [...] end; Dadurch verschwindet der Eintrag zwar in der Listenansicht, aber in der Itunes - Datenbank bzw. der daraus generierten XML-Datei steht nach wie vor ein 'leerer' String mit der Länge 1: <key>EpisodeID</key><string> </string>. Mit einem VB-Script funktioniert die Zuweisung eines Leerstrings (track.EpisodeID="") dagegen erwartungsgemäß: Der Eintrag wird komplett entfernt. Ich habe leider wenig Erfahrung mit Interfaces unter Delphi. Ist es generell unzulässig, einen Leerstring zuzuweisen, oder geht das irgendwie ganz anders? Oder handelt es sich um einen Fehler der Type-Libraray? Als Workaround könnte ich aus meinem Programm ein VB-Script starten, aber das wäre wirklich nur eine Notlösung. Es wäre schön, wenn mir da jemand weiterhelfen könnte. Gruß LP |
AW: Leerstring bei Interface
Eigentlich sollte das kein Problem sein, aber vielleicht hilft es, den Leerstring als lokale Konstante anzulegen und diese dann zuzuweisen:
Delphi-Quellcode:
procedure ClearTrack(track: IITFileOrCDTrack);
const EmptyString = ''; begin track.EpisodeID := EmptyString; end; |
AW: Leerstring bei Interface
Zitat:
Gruß LP |
AW: Leerstring bei Interface
Auf nil setzen?
|
AW: Leerstring bei Interface
Zitat:
Delphi-Quellcode:
Aber ich würde mich nicht wundern, wenn das auf dasselbe hinausläuft wie der Leerstring.track.Set_EpisodeID(PWideString(nil)^); |
AW: Leerstring bei Interface
Ehrlich gesagt, versteh ich nicht, warum '' oder sonstwo aus irgendwelchen typisierten oder untypisierten Konstanten/Variablen.
Selbst wenn es der falsche String-Typ ist, dann konvertiert Delphi das automatisch. ACHTUNG: Variant vs. OleVariant Im Variant können Delphi-Typen enthalten sein, wie z.B. AnsiString und String/UnicodeString, womit fremde Sprachen natürlich nicht zurechtkommen, da sie das nicht kennen. Der OleVariant ist ein OLE-kompatibler Variant, welcher ausschließlich Typen enthalten kann, welche OLE kennt, da sie dort definiert wurden. Also entweder OleVariant verwenden, oder ihr müsst eine typisierte Konstante benutzen (WideString oder OleVariant), mit dem passenden Typen, welchen OLE kennt.
Delphi-Quellcode:
const EmptyString: WideString = '';
[edit] war grad gedanklich bei einem anderen Probleme, was hier vor einer Weile im Forum war, auch mit einem OLE-Interface. Auch zu beachten: Die SysUtils kennt ebenfalls ein ![]() Und ich würde es als gefährlich einstufen diese Konstante zu benutzen.
Code:
Wir hatten z.B. mal den Spaß, dass diese Konstante ausversehn überschrieben wurde, mit dem Wert
if S = '' then
004E63CB 837DF800 cmp dword ptr [ebp-$08],$00 004E63CF 7507 jnz $004e63d8 Unit1.pas.31: if S = EmptyStr then 004E63D8 8B45F8 mov eax,[ebp-$08] 004E63DB 8B15DC514F00 mov edx,[$004f51dc] 004E63E1 8B12 mov edx,[edx] 004E63E3 E8BC4DE3FF call $0031b1a4 004E63E8 7507 jnz $004e63f1
Delphi-Quellcode:
,
'Empty'
und da DevExpress in seinem QuantumGrid überall diese Konstante verwendet, standen dann in allen leeren Zellen (mit NULL) plötzlich ÜBERALL "Empty" drin. |
AW: Leerstring bei Interface
Zitat:
So geht's also offenbar auch nicht :( Gruß LP |
AW: Leerstring bei Interface
Es ist das Selbe.
Abgesehn von ShortString's ist ein leerer String per se ein NIL. Theoretisch wäre es möglich, dass es auch nicht nil ist, mit der Length=0, aber grundsätzlich kommt sowas eigentlich nie vor. Andere Ausnahme ist PChar(''), welches nicht NIL zurück gibt, sondern einen Zeiger auf einen Speicher, wo zwei #0 drin stecken. (was mache API nicht mag) Kann es sein, dass hier IMMER eine ID reingegeben werden MUß, womit ein Leerstring quasi verboten ist? Ist deine Interface-Instanz überhaupt OK? (IITFileOrCDTrack) Sicher, dass es wirklich safecall ist? $C0000005 = Fatal + AccessViolation 0x00000000 = z.B. NIL 0x013f9a80 = was ist hier? Beim Debuggen ein Strg+Alt+M und dann schauen, wo dieses drin ist (also was die nächst kleinere Basisadresse besitzt) |
AW: Leerstring bei Interface
Zitat:
|
AW: Leerstring bei Interface
Liste der Anhänge anzeigen (Anzahl: 1)
Well it could be helpful and insightful if you can share a small memory dump for the data pointed by that EpisodeID, use the debugger and capture a screenshot of that address content and most importantly few bytes before it like 4 (if it is BSTR for real) like this
Anhang 56874 Anyway, from reading this : ![]() Can you try SysFreeString and see if that clear the string without problem ? ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:58 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz