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.