I'm trying to figure out how to use WinAPI functions from Pascal Script/Inno Setup. I didn't find much code examples how to do it and I'm not a Pascal programmer. Here's what I did so far:
Importing the function
function PathCombine (
pszPathOut : PChar;
pszPathIn : PChar;
pszMore : PChar
) : PChar;
external 'PathCombineA@Shlwapi.dll stdcall';
and using it like this:
function InitializeSetup(): Boolean;
var
a, b,c : PChar;
s : string;
begin
SetLength(s, 256); { soon it gets working I'll switch to use MAX_PATH instead of }
a := 'C:';
b := 'one\two';
c := PathCombine(s, a, b);
MsgBox(s, mbInformation, MB_OK);
end;
The output is this:
The expected output is:
C:\\one\\two
I'm pretty sure I'm accessing garbage values in memory but I don't know why, how do I fix this?
You didn't specify if you are using Ansi or Unicode version of Inno Setup.
But this should work in either version:
function PathCombine(
pszPathOut : PAnsiChar;
pszPathIn : PAnsiChar;
pszMore : PAnsiChar
) : PAnsiChar; external 'PathCombineA@Shlwapi.dll stdcall';
function InitializeSetup(): Boolean;
var
a, b, c: AnsiString;
begin
SetLength(c, 256); { soon it gets working I'll switch to use MAX_PATH instead of }
a := 'C:';
b := 'one\two';
PathCombine(c, a, b);
MsgBox(c, mbInformation, MB_OK);
Result := True;
end;
Though I strongly encourage you to use Unicode version of Inno Setup and PathCombineW
instead.
function PathCombine(
pszPathOut : string;
pszPathIn : string;
pszMore : string
) : Cardinal; external 'PathCombineW@Shlwapi.dll stdcall';
function InitializeSetup(): Boolean;
var
a, b, c: string;
begin
SetLength(c, 256); { soon it gets working I'll switch to use MAX_PATH instead of }
a := 'C:';
b := 'one\two';
PathCombine(c, a, b);
MsgBox(c, mbInformation, MB_OK);
Result := True;
end;
Note that Inno Setup lacks PWideChar
type. While it can marshal string
to LPTSTR
( PWideChar
) function arguments, it cannot marshal LPTSTR
return value. So I've used Cardinal
for return type. It has the same size as pointer (to char), so a stack will match. And we do not actually need the returned value.
I think (although I haven't worked with Pascal / Delphi for a while) that the problem is that C "strings" ( char *
) are 0 index based, while Pascal strings are 1 index based (byte 0 is used to store the length).
So, if you declare your s
variable as:
s: array[0..255] of Char; //Don't forget to change it to MAX_PATH afterwards
it should work. Also use the PathCombine
function like this:
PathCombine(s, a, b);
There's no need to assign its result (which is the same as s
) to another variable (that you aren't going to use anyway).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.