Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi PChar schneidet letztes Zeichen ab (https://www.delphipraxis.net/78531-pchar-schneidet-letztes-zeichen-ab.html)

TheMiller 6. Okt 2006 14:06


PChar schneidet letztes Zeichen ab
 
Hallo,

da ich Werte mit Hilfe einer DLL Werte aus der Registry auslese, verwende ich zur Stringübertragung PChar. Doch ich habe einen Wert in der Registry, bei dem - und nur bei dem - schneidet er mit das letzte Zeichen ab. Verändere ich den Wert in der Registry um einen Buchstaben, so wird der zuvor abgeschnittene UND der neue mit angezeigt.

Was ist den da bitte jetzt wieder los?

Go2EITS 6. Okt 2006 14:26

Re: PChar schneited letztes Zeichen ab
 
Bin zwar nicht so fit mit der Registry, aber die Routinen zum Lesen eines Eintrages und zum Setzen müssten funktionieren. "Zeig mal Code", wie es schön heißt..

3_of_8 6. Okt 2006 14:28

Re: PChar schneidet letztes Zeichen ab
 
Hat vielleicht irgendwas damit zu tun, dass ein PChar von einem #0 terminiert wird.

DGL-luke 6. Okt 2006 14:39

Re: PChar schneidet letztes Zeichen ab
 
Dann sag uns doch mal, wie der wert aussieht...

TheMiller 6. Okt 2006 14:45

Re: PChar schneidet letztes Zeichen ab
 
Der Wert lautet ganz einfach:

InstallDir - C:\Programme\MyProg\Test

und das "t" wird abgeschnitten. Hänge ich ein "s" dran (Tests) dann wird "C:\Programme\MyProg\Tests" ausgegeben! Was ist da los? *g*

TheMiller 6. Okt 2006 14:45

Re: PChar schneidet letztes Zeichen ab
 
Was bedeuted ein #0 ?

mkinzler 6. Okt 2006 14:48

Re: PChar schneidet letztes Zeichen ab
 
Zitat:

Was bedeuted ein #0 ?
ASCII 0 markiert das Ende eines Strings (EOS) in c/c++

DGL-luke 6. Okt 2006 14:49

Re: PChar schneidet letztes Zeichen ab
 
Warum Doppelpost?

Die Windows-API arbeitet mit nullterminierten Strings. Das heißt, es wird ein Pointer auf einen Speicherbereich übergeben. Das Ende des Strings wird von einem #0 gekennzeichnet.

Und wenn du uns jetzt noch kurzdeien Code zeigst...

TheMiller 6. Okt 2006 15:05

Re: PChar schneidet letztes Zeichen ab
 
Delphi-Quellcode:
// DLL
function GetInstallDir: PChar; stdcall;
var
  Reg:TRegistry;
begin
  Reg:=TRegistry.Create;
  Reg.RootKey:=HKEY_CURRENT_USER;
  Reg.OpenKey('Software\MyProg\Test\', false);
  result:=PChar(Reg.ReadString('InstallDir'));
end;


//Programm
function GetInstallDir: PChar; stdcall; external SysCtrl;

ShowMessage(PChar(GetInstallDir));

Luckie 6. Okt 2006 15:06

Re: PChar schneidet letztes Zeichen ab
 
Zitat:

Zitat von Raymond Chen
Even though a value is stored in the registry as REG_SZ, this doesn't mean that the value actually ends with a proper null terminator.

Schreibst du den Wert eventuell nicht richtig rein?

Roter Kasten:
Deine Methode mit den PChar kommt mir etwas komisch vor. Hier mal ein Auszug aus einer DLL von mir, die auch mit PChar arbeitet.
Delphi-Quellcode:
function ReturnString(InStr: PChar; Buffer: PChar; lenBuffer: Integer): Integer; stdcall
var
  cls              : JClass;
  mid              : JMethodID;
  res              : JString;
  instance         : JObject;
  s: String;
begin
  cls := jvm.JniEnv.FindClass('HelloWorld');
  Assert(Assigned(cls), 'Class HelloWorld not found');

  mid := jvm.JniEnv.GetMethodID(cls, '<init>', '()V');
  Assert(Assigned(mid), 'Constructor not found');

  instance := jvm.JniEnv.NewObject(cls, mid, []);
  // Signatur: String Parameter, Rückgabetyp String
  mid := jvm.JniEnv.GetMethodID(cls, 'strTest2', '(Ljava/lang/String;)Ljava/lang/String;');
  Assert(Assigned(mid), 'Method "strTest2" not found');

  res := jvm.JniEnv.CallObjectMethod(instance, mid, [String(InStr)]);

  s := jvm.JniEnv.JStringToString(res);

  if length(s) < lenBuffer then
  begin
    result := Length(s);
  end
  else
  begin
    lstrcpy(Buffer, PChar(s));
    result := Length(s);
  end;
end;
Was sie letztendlich macht ist egal. Wichtig ist nur der letzte Teil.

Aufruf aus dem Programm dann:
Delphi-Quellcode:
procedure TForm1.btnRetStrClick(Sender: TObject);
type
  TReturnStr = function(InStr: PChar; Buffer: PChar; lenBuffer: Integer): Integer; stdcall;
var
  ReturnStr        : TReturnStr;
  Buffer           : PChar;
  len              : Integer;
begin
  Buffer := nil;
  @ReturnStr := GetProcAddress(hLib, 'ReturnString');
  if Assigned(ReturnStr) then
  begin
    len := ReturnStr('Hello ', nil, 0);
    try
      GetMem(Buffer, len + 1);
      ReturnStr('Hello ', Buffer, len);
      StB.SimpleText := string(Buffer);
    finally
      FreeMem(Buffer, len + 1);
    end;
  end
  else
    StB.SimpleText := SysErrorMessage(GetLastError);
end;
Prinzip: Die DLL-Funktion gibt die Länge zurück. Ich rufe sie erst mit nil auf, sie schlägt dann fehl und sagt mir, wie groß der Buffer sein muss. Dann alloziiere ich entsprechend Speicher und rufe sie mit einem Zeiger auf einem entsprechend großen Speicherbereich auf.
Das ist auch die übliche Vorgehensweise bei entsprechenden Windows-API Funktionen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:53 Uhr.
Seite 1 von 3  1 23      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz