![]() |
Typumwandlung string -> PAnsiChar
Hallo zusammen,
ich hab mit Unicode noch so meine Probleme: wenn ich einen String h habe und brauche aber einen PAnsiChar dann kann man ja PAnsiChar(h) machen. Der Compiler meldet dann: [DCC Warnung] Allg_win.pas(162): W1044 Bedenkliche Typumwandlung von string in PAnsiChar die .exe tut dann auch nicht das was sie soll. Aber ich krieg es einfach nicht 'unbedenklicher hin' unter W1044 Bedenkliche Typumwandlung von AnsiString in PWideChar gab es zwar sowas änliches aber schlau werd ich da nicht draus. Kann mir jemand einen Tip geben? |
Re: Typumwandlung string -> PAnsiChar
Das liegt daran, das der normale String unter D2010 ein Multibyte String ist. D.h. wenn du einen String auf pAnsiChar castest, geht das eigentlich immer in die Hose. Ein pAnsiChar ( Zeiger auf ein AnsiString) ist kein Multibyte. Du musst es schon auf pWideChar casten oder Utf8Encode und Utf8Decode benutzten um dein String als AnsiString zu nutzten
|
Re: Typumwandlung string -> PAnsiChar
Hört sich gut an, nützen tut es nichts
Der Compiler gibt nur Fehlermeldungen aus. Umwandlungsroutinen gibt es zuhauf, eventuell mehr als nötig, aber auch mit 'try by error' Probiermethode find ich keine Lösung. (Utf8Encode und Utf8Decode liefert auch nur Fehler) Wäre ein Beispiel möglich? Es handelt sich um die Unit Mapi in Delphi 5 hat einwandfrei funktioniert:
Delphi-Quellcode:
wobei Mail: mail: TStringList;
Receip.lpszName:= StrNew(Mail.Values['to']);
und Receip: TMapiRecipDesc; (unit mapi) in Delphi 10 geht diese Zeile nicht mehr, es wird ein PAnsiChar erwartet. WIE GEHT DAS |
Re: Typumwandlung string -> PAnsiChar
Der Fehler liegt, wie bereits angedeutet, in deinem Verständnis. Ein String war in alten Delphiversionen ein Array von Chars mit einigen Zusatzinformationen. In neuen Delphiversionen ist ein String aber kein Array von Chars mehr.
Ein PAnsiChar ist wiederum nur ein Pointer welcher auf einen Char zeigt. Wenn dein String jetzt aber nicht mehr aus Chars besteht kannst du natürlich den Pointer auch nicht mehr auf Chars zeigen lassen. Entsprechend ist das völlig inkompatibel. Du müsstest also entweder etwas anderes Anstelle des Strings verwenden (was intern ein Array von Chars ist) oder du musst einen anderen Pointertypen verwenden der nicht auf Chars zeigt sondern so typisiert ist, dass er mit dem Zeichen eines neuen Strings kompatibel ist. |
Re: Typumwandlung string -> PAnsiChar
Also dann probier ich es nochmal anderherum:
es gab mal eine Prozedur (stammt nicht von mir):
Delphi-Quellcode:
die man problemlos so nutzen konnte:
// uses MAPI
function SendEMail(Handle:THandle; Mail:TStrings):Cardinal; type TAttachAccessArray= array [0..0] of TMapiFileDesc; PAttachAccessArray= ^TAttachAccessArray; var MapiMessage: TMapiMessage; Receip: TMapiRecipDesc; Attachments: PAttachAccessArray; AttachCount: Integer; i1: integer; FileName: string; dwRet: Cardinal; MAPI_Session: Cardinal; WndList: Pointer; begin Result:= MAPI_E_FAILURE; dwRet:= MapiLogon(Handle, PAnsiChar(''), PAnsiChar(''), MAPI_LOGON_UI or MAPI_NEW_SESSION, 0, @MAPI_Session); if (dwRet<>SUCCESS_SUCCESS) then begin MessageBox(Handle, PChar('Error while trying to send email'), PChar('Error'), MB_ICONERROR or MB_OK); end else begin FillChar(MapiMessage, SizeOf(MapiMessage), #0); Attachments:= nil; FillChar(Receip, SizeOf(Receip), #0); if Mail.Values['to']<>'' then begin Receip.ulReserved:= 0; Receip.ulRecipClass:= MAPI_TO; Receip.lpszName:= StrNew(Mail.Values['to']); Receip.lpszAddress:= StrNew('SMTP:' + Mail.Values['to']); Receip.ulEIDSize:= 0; MapiMessage.nRecipCount:= 1; MapiMessage.lpRecips:= @Receip; end; AttachCount:=0; for i1:=0 to MaxInt do begin if Mail.Values['attachment' + IntToStr(i1)] = '' then break; Inc(AttachCount); end; if AttachCount>0 then begin GetMem(Attachments, SizeOf(TMapiFileDesc) * AttachCount); for i1:=0 to AttachCount-1 do begin FileName:= Mail.Values['attachment' + IntToStr(i1)]; Attachments[i1].ulReserved:= 0; Attachments[i1].flFlags:= 0; Attachments[i1].nPosition:= ULONG($FFFFFFFF); Attachments[i1].lpszPathName:= StrNew(FileName); Attachments[i1].lpszFileName:= StrNew(ExtractFileName(FileName)); Attachments[i1].lpFileType:= nil; end; MapiMessage.nFileCount := AttachCount; MapiMessage.lpFiles := @Attachments^; end; if Mail.Values['subject']<>'' then MapiMessage.lpszSubject:= StrNew(Mail.Values['subject']); if Mail.Values['body']<>'' then MapiMessage.lpszNoteText:= StrNew(Mail.Values['body']); WndList := DisableTaskWindows(0); try Result:= MapiSendMail(MAPI_Session, Handle, MapiMessage, MAPI_DIALOG, 0); finally EnableTaskWindows(WndList); end; for i1:=0 to AttachCount-1 do begin StrDispose(Attachments[i1].lpszPathName); StrDispose(Attachments[i1].lpszFileName); end; if Assigned(MapiMessage.lpszSubject) then StrDispose(MapiMessage.lpszSubject); if Assigned(MapiMessage.lpszNoteText) then StrDispose(MapiMessage.lpszNoteText); if Assigned(Receip.lpszAddress) then StrDispose(Receip.lpszAddress); if Assigned(Receip.lpszName) then StrDispose(Receip.lpszName); MapiLogOff(MAPI_Session, Handle, 0, 0); end; end;
Delphi-Quellcode:
Das geht jetzt offensichtlich nicht mehr. PAnsiChar hin oder her ist mir eigentlich völlig egal.
procedure TTestForm.Mail1Click(Sender: TObject);
var mail: TStringList; begin mail:= TStringList.Create; try mail.values['to']:= 'fifi@xyz.de'; mail.values['subject']:= 'test'; mail.values['body']:= 'Text Text Text'; mail.values['attachment0']:= 'C:\Anhang.txt'; SendEMail(Self.Handle, mail); finally mail.Free; end; end; Gibt es eine alternative Möglichkeit eine Mail zu versenden ohne die geheimnisvollen Konvertierungen von PAnsiChar offenbaren zu müssen? |
Re: Typumwandlung string -> PAnsiChar
Ist doch eigentlich ganz einfach; man braucht einen AnsiString als Zwischenspeicher:
Delphi-Quellcode:
var
to_addr : AnsiString; begin ... to_addr := Mail.Values['to']; // UnicodeString auf AnsiString kopieren Receip.lpszName:= PAnsiChar(to_addr); |
Re: Typumwandlung string -> PAnsiChar
Super, DANKE!!!
Jetzt hab ich auch kapiert was eingangs gemeint war. Manchmal braucht's einfach was anschauliches. |
AW: Typumwandlung string -> PAnsiChar
ich versuche gerade mit folgender funktion eine destkopverknüpfung zu speichern. jedoch geht meine pfadangabe bis auf ein simpes "C" komplett verloren.
wie erreiche ich es, dass die verknüpfung erstellt wird und der pfad erhlten bleibt?
Delphi-Quellcode:
function TGenFunctions.createLink(const AFileName, AParameter: string): Boolean;
var psl: IShellLink; ppf: IPersistFile; wsz: PWideChar; begin Result := False; if SUCCEEDED(CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_inPROC_SERVER, IID_IShellLinkA, psl)) then begin psl.SetPath(PWideChar(AFileName)); psl.SetArguments(PChar(AParameter)); psl.SetWorkingDirectory(PChar(ExtractFilePath(AFileName))); if SUCCEEDED(psl.QueryInterface(IPersistFile, ppf)) then begin GetMem(wsz, max_path * 2); try MultiByteToWideChar(CP_ACP, 0, 'C:\Users\testaccount\Desktop\test.lnk'), -1, wsz, max_path); // hier tritt der fehler auf und der hinweis "bedenkliche umwandlung" ppf.Save(wsz, True); Result := True; finally FreeMem(wsz, max_path * 2); end; end; end; end; |
AW: Typumwandlung string -> PAnsiChar
In diesem
![]() Probiere es mal so :
Delphi-Quellcode:
MultiByteToWideChar(CP_ACP, 0, 'C:\Users\testaccount\Desktop\test.lnk', -1, wsz, max_path);
|
AW: Typumwandlung string -> PAnsiChar
Zitat:
Delphi gibt dir hier zwar einen Zeiger darauf, aber warnnt dich, daß die Daten im "falschen" Format vorliegen. Also entweder vorher in eine Stringvariable vom richtigen Typen umkopieren, oder
Delphi-Quellcode:
var
s: UnicodeString; P: PAnsiChar; p := PAnsiChar(AnsiString(s));
Delphi-Quellcode:
ist kein reiner Type-Cast, denn die Compilermgic legt hier eine temporäre AnsiString-Variable an, welche meistens bis zum Ende der Prozedur erhalten bleibt.
AnsiString(s)
Und PAnsiChar zeigt dann in Wirklichkeit auf diese temporäre Varible, welche eine umgewandelte Kopie von S enthält. Kommt nun darauf an, wie langlebig dieser Pointer sein muß. Wenn es nur als direkter Parameter für einen einzigen Funktionsaufruf sein soll, dann gibt es absolut keine Probleme, aber wenn man sich z.B. an einer Stelle den Pointer besort und erst mehrere Codezeilen weiter unten diesen Pointer verwendet, dann wäre es sicherer, wenn man sich eine eigene AnsiString-Variable anlegt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:35 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 by Thomas Breitkreuz