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.