Einzelnen Beitrag anzeigen

Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#28

Re: PChar schneidet letztes Zeichen ab

  Alt 6. Okt 2006, 21:22
Als ich auf dem Parkplatz auf meine Freundin gewartet habe, habe ich mir noch mal gedanken über die Längenangaben gemacht. Die haben mir keine Ruhe gelassen, was heißt, dass da irgendwas nicht ganz stimmte. Hier noch mal der überarbeitet Code.

DLL
Delphi-Quellcode:
(******************************************************************************
*                                                                            *
*  StringDLL                                                                *
DLL zum Demo-Programm DLLProg                                            *
*                                                                            *
*  Copyright (c) 2006 Michael Puff  [url]http://www.michael-puff.de[/url]              *
*                                                                            *
******************************************************************************)


library StringDLL;

uses
  SysUtils;

function func1(s: PChar; Buffer: PChar; lenBuffer: Integer): Integer; stdcall;
var
  foo: String;
begin
  // Strings aneinanderhängen
  foo := 'foo'+ s;
  // wenn Stringlänge kleiner oder gleich lang wie lenBuffer
  // String in Buffer kopieren
  if length(foo) < lenBuffer then
  begin
    StrLCopy(Buffer, PChar(foo), lenBuffer);
  end;
  // auf alle Fälle immer Länge des Strings zurückgeben
  result := length(foo);
end;

exports
  func1;

begin
end.
Programm:
Delphi-Quellcode:
(******************************************************************************
*                                                                            *
*  DLLProg                                                                  *
*  Demo-Programm Strings und DLLs                                            *
*                                                                            *
*  Copyright (c) 2006 Michael Puff  [url]http://www.michael-puff.de[/url]              *
*                                                                            *
******************************************************************************)


program DLLProg;

{$APPTYPE CONSOLE}

uses
  windows;

type
  Tfunc1 = function(s: PChar; Buffer: PChar; lenBuffer: Integer): Integer; stdcall;

var
  hLib: THandle;
  s: String;
  func1: Tfunc1;
  len: Integer;
  Buffer: PChar;

begin
  Buffer := nil;

  // DLL laden
  hLib := LoadLibrary('StringDLL.dll');
  if hLib = 0 then
  begin
    Str(GetLastError, s);
    Writeln(s);
    readln;
    exit;
  end;
  Str(hLib, s);
  Writeln('hlib: ' + s);
  // Adresse der exportierten Funktion holen
  @func1 := GetProcAddress(hLib, 'func1');
  if (not Assigned(func1)) then
  begin
    Str(GetLastError, s);
    Writeln(s);
    readln;
    exit;
  end;
  Str(Integer(@func1), s);
  Writeln('@func1: ' + s);
  // Funktion aufrufen, um Größe des Buffers zu ermitteln
  len := func1('bar', nil, 0);
  Str(len, s);
  Writeln('len: ' + s);
  try
    // Speicher anforden
    GetMem(Buffer, len + 1);
    // Funktion mit Buffer aufrufen
    len := func1('bar', Buffer, len + 1);
    Str(len, s);
    // Buffer ausgeben
    writeln(String(Buffer)+ ' [' + s + ']');
  finally
    // Speicher wieder freigeben
    FreeMem(Buffer);
  end;
  readln;
end.
Ich hoffe so stimmt das jetzt. Die Compilermagic kann manch mal ganz schön stören, wenn man nicht weiß, ob sie den String jetzt automatisch nullterminiert oder nicht und so was.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat