![]() |
String zu PAnsiChar
Hallo, auch auf die Gefahr hin, daß ich langsam nerve,
aber ich hab es noch nicht kapiert, die folgende einfache Prozedur zeigt mein Problem:
Delphi-Quellcode:
PAnsiChar(AnsiString(s[i])) war das bisherige Fazit, ist aber offensichtlich nicht richtig oder nicht ausreichend.
procedure TTestForm.Test2Click(Sender: TObject);
var s: TStrings; i:integer; x: array of PAnsiChar; begin s:= TStringList.Create; s.Add('#0#'); s.Add('#1#'); s.Add('#2#'); SetLength(x, 3); for i:=0 to 2 do x[i]:= PAnsiChar(AnsiString(s[i])); for i:=0 to 2 do showmessage(x[i]); // liefert: #2# #2# #2# WARUM ???????????????????ß x[0]:='##0##'; x[1]:='##1##'; x[2]:='##2##'; for i:=0 to 2 do showmessage(x[i]); // -> liefert: ##0## ##1## ##2## Finalize(x); s.Free; end; Wie bekommt man die Strings von s in das array? |
Re: String zu PAnsiChar
Delphi-Quellcode:
müsste richtig sein.
for i:=0 to 2 do x[i]:= PAnsiChar(AnsiString(s.strings[i]));
|
Re: String zu PAnsiChar
Servus, zunächst einmal kann das ja gar nich funktionieren, da ein PAnsiChar auf einen Character zeigt, also nur ein Zeichen.
Hab dein Codeschnipsel mal etwas abgewandelt:
Delphi-Quellcode:
Die abgeänderten Stellen sind markiert.
procedure TForm1.Button2Click(Sender: TObject);
var s: TStrings; i:integer; x: array of PAnsiString; //hier begin s:= TStringList.Create; s.Add('#0#'); s.Add('#1#'); s.Add('#2#'); SetLength(x, 3); for i:=0 to 2 do x[i]:= PAnsiString(s[i]); //hier for i:=0 to 2 do showmessage(AnsiString(x[i])); //hier Finalize(x); s.Free; end; |
Re: String zu PAnsiChar
So funktioniert es:
Delphi-Quellcode:
x[i]:=StrNew(pAnsiChar(AnsiString(s[i])));
|
Re: String zu PAnsiChar
Danke an daywalker9 das ist es!!! :dancer2:
|
Re: String zu PAnsiChar
Jetzt bleibt nur die Frage:
Reicht da Finalize(x); oder muß zuvor noch für jedes StrDispose[i]; her? |
Re: String zu PAnsiChar
Es reicht eigentlich wenn du für alle Elemente im Array StrDispose() aufrufst.
|
Re: String zu PAnsiChar
Nun habt ihr mich aber neugierig gemacht:
Was sind denn ##0## bzw. ##1## oder ##2##? Bisher sind mit nur die ASCII-Zeichen wie #10 (= line feed) etc. bekannt. Die genannte Schreibweise ist mir neu. |
Re: String zu PAnsiChar
Das hat garnichts mit Steuerzeichen zu tun, das waren lediglich Beispielstrings.
Der Hintergrung ist die Unit Mapi um eMails mit dem Standard eMail-client zu versenden. Hat in Delphi2010 nicht mehr funktioniert. Aber jetzt klappt's wieder; wer's gebrauchen kann:
Delphi-Quellcode:
so zu verwenden:
function SendEMail(Handle:THandle; Mail:TStrings):Cardinal;
var MapiMessage: TMapiMessage; Receip: TMapiRecipDesc; Attachments: array of TMapiFileDesc; i, AttachCount: Integer; FileName: string; MAPI_Session: Cardinal; WndList: Pointer; begin Result:= MAPI_E_FAILURE; if (MapiLogon(Handle, PAnsiChar(''), PAnsiChar(''), MAPI_LOGON_UI or MAPI_NEW_SESSION, 0, @MAPI_Session) <> SUCCESS_SUCCESS) then MessageBox(Handle, PChar('Error while trying to send email'), PChar('Error'), MB_ICONERROR or MB_OK) else begin if Mail.Values['to']<>'' then begin Receip.ulReserved:= 0; Receip.ulRecipClass:= MAPI_TO; Receip.lpszName:= PAnsiChar(AnsiString(Mail.Values['to'])); Receip.lpszAddress:= PAnsiChar(AnsiString('SMTP:' + Mail.Values['to'])); Receip.ulEIDSize:= 0; MapiMessage.nRecipCount:= 1; MapiMessage.lpRecips:= @Receip; end; if Mail.Values['subject']<>'' then MapiMessage.lpszSubject:= PAnsiChar(AnsiString(Mail.Values['subject'])); if Mail.Values['body']<>'' then MapiMessage.lpszNoteText:= PAnsiChar(AnsiString(Mail.Values['body'])); AttachCount:= 0; for i:= 0 to MaxInt do begin if Mail.Values['attachment' + IntToStr(i)] = '' then break; Inc(AttachCount); end; SetLength(Attachments, AttachCount); if AttachCount>0 then begin for i:=0 to AttachCount-1 do begin FileName:= Mail.Values['attachment' + IntToStr(i)]; Attachments[i].ulReserved:= 0; Attachments[i].flFlags:= 0; Attachments[i].nPosition:= ULONG($FFFFFFFF); Attachments[i].lpszPathName:= StrNew(PAnsiChar(AnsiString(FileName))); Attachments[i].lpszFileName:= StrNew(PAnsiChar(AnsiString(ExtractFileName(FileName)))); Attachments[i].lpFileType:= nil; end; MapiMessage.nFileCount := AttachCount; MapiMessage.lpFiles := Pointer(Attachments); end; WndList:= DisableTaskWindows(0); try Result:= MapiSendMail(MAPI_Session, Handle, MapiMessage, MAPI_DIALOG, 0); finally EnableTaskWindows(WndList); for i:=0 to AttachCount-1 do begin StrDispose(Attachments[i].lpszPathName); StrDispose(Attachments[i].lpszFileName); end; Finalize(Attachments); end; MapiLogOff(MAPI_Session, Handle, 0, 0); end; end;
Delphi-Quellcode:
Allerdings gab' hierzu mehrmals die Bemerkung, daß Mapi bereits fast tot ist.
procedure TTestForm.Mail1Click(Sender: TObject);
var mail: TStringList; begin mail:= TStringList.Create; try mail.values['to']:= 'fifi@abc.de'; mail.values['subject']:= 'subject'; mail.values['body']:= 'text text text'; mail.values['attachment0']:= 'C:\Anhang1.txt'; mail.values['attachment1']:= 'C:\Anhang2.txt'; mail.values['attachment2']:= 'C:\Anhang3.txt'; SendEMail(Self.Handle, mail); finally mail.Free; end; end; Ich hab auch bei Indy geschaut, aber so wie ich das dort verstanden hab, geht der eMail versand dann nicht über das Mailprogramm Thundrbird outlook etc. ist also dort nicht drin, was ich aber will. Ausserdem dar ganze Anmeldekram Aber wenn das auch mit Indy geht lass ich mich gerne aufklären. |
AW: String zu PAnsiChar
Ich beschäftige mich auch gerade mit solchen Stringumwandlungen und da erhalte ich eine Accessviolation beim Beenden meines Programmes, obwohl der String zunächst korrekt angezeigt wird, an folgender Stelle in der System Unit, wie mir mein Debugger zeigt (Delphi 10.3.3 Community Edition). Kann der Quellcode aus der System Unit hier so stehen bleiben?
Delphi-Quellcode:
Hier mein Quellcode zu verschiedenen Stringkonvertierungen:
procedure _UStrClr(var S);
{$IFDEF CPUX86} asm { -> EAX pointer to str } { <- EAX pointer to str } MOV EDX,[EAX] { fetch str } TEST EDX,EDX { if nil, nothing to do } JE @@done MOV dword ptr [EAX],0 { clear str } MOV ECX,[EDX-skew].StrRec.refCnt { fetch refCnt } /// Hier knallt es DEC ECX { if < 0: literal str } JL @@done LOCK DEC [EDX-skew].StrRec.refCnt { threadsafe dec refCount } JNE @@done
Delphi-Quellcode:
Warum wird da diese Exception geworfen, was muss ich da anders machen?
program Strconv;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, Windows; var AnsiStr: AnsiString; AnsiChr: PAnsiChar; WideStr: WideString; WideChr: PWideChar; procedure AnsiStrToWideStr(aStr: AnsiString; var waStr: WideString); begin waStr := aStr; end; procedure AnsiStrToPAnsiChr(aStr: AnsiString; var paChr: LPCSTR); begin paChr := PAnsiChar(aStr); end; procedure AnsiStrToPWideChar(aStr: AnsiString; var pwChr: LPCWSTR); var ws: WideString; begin ws := aStr; pwChr := LPCWSTR(ws); end; procedure PWideCharToWideString(pwChr: LPCWSTR; var ws: WideString); //Diese Prozedur macht die Probleme var wchr: array of WideChar absolute pwChr; i: Integer; wch: array of WideChar; begin SetLength(wch,StrLen(pwChr)); move(wchr,ws,StrLen(pwChr)); ws := WideString(wchr); end; { procedure PWideCharToPAnsiChar(pwChr: LPCWSTR; var a: LPCSTR); var wchr: array of WideChar absolute pwChr; ansiStr: AnsiString; wideStr: WideString; begin move(wchr,wideStr,StrLen(pwChr)); //PWideCharToWideString(pwChr,wideStr); ansiStr := WideStr; a := @ansiStr; end; } procedure PWideCharToAnsiString(pwChr: LPCWSTR; var s: AnsiString); var wideStr: WideString; begin PWideCharToWideString(pwChr,wideStr); s := AnsiString (WideStr); end; begin try { TODO -oUser -cConsole Main : Code hier einfügen } AnsiStr := 'Dieser String'; //AnsiStrToPAnsiChr(AnsiStr,AnsiChr); //AnsiStrToWideStr(AnsiStr,WideStr); AnsiStrToPWideChar(AnsiStr,WideChr); //PWideCharToPAnsiChar(WideChr,AnsiChr); //PWideCharToWideString(WideChr,WideStr); //PWideCharToPAnsiChar(WideChr,AnsiChr); funktioniert nicht PWideCharToAnsiString(WideChr,AnsiStr); writeln(AnsiStr); //wird korrekt angezeigt readln; //Nach Drücken der Enter Taste zum Beenden meines Programmes kommt die Exceptioen EAccessviolation. except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. Ist zwar ein uralter Thread, aber dessen Thema passt so gut zu meinem Problem. . |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:40 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