var
i, iSize: Integer;
SourceId: Cardinal;
szValue1: PChar;//array[0..MAX_PATH - 1] of Char;
szValue2: PChar;//array[0..MAX_PATH - 1] of Char;
sValue1, sValue2: string;
begin
iSize := MAX_PATH * SizeOf(Char);
szValue1 := GetMemory(MAX_PATH * SizeOf(Char));
szValue2 := GetMemory(MAX_PATH * SizeOf(Char));
try
for i := 0 to AList.Count - 1 do
begin
ZeroMemory(szValue1, iSize);
if SetupGetSourceFileLocation(AInf, nil, PChar(AList.Strings[i]),
SourceId, szValue1, MAX_PATH, nil) then
begin
// sValue1 := szValue1;
SetLength(sValue1, lstrlen(szValue1));
CopyMemory(@sValue1[1], szValue1, lstrlen(szValue1) * SizeOf(Char));
ZeroMemory(szValue2, iSize);
if SetupGetSourceInfo(AInf, SourceId, SRCINFO_PATH, szValue2,
MAX_PATH, nil) then
begin
// sValue2 := szValue2;
//第二次循环时,此处报错,不管是直接赋值还是用CopyMemory,字符szValue为Char数组和PChar都试过。
SetLength(sValue2, lstrlen(szValue2));
CopyMemory(@sValue2[1], szValue2, lstrlen(szValue2) * SizeOf(Char));
end
else
szValue2 := '';
OutputDebugString(PChar(sValue2 + '\' + sValue1));
end;
end;
finally
FreeMemory(szValue1);
FreeMemory(szValue2);
end;
end;
SetupGetSourceFileLocation和SetupGetSourceInfo可查看msdn
为什么你把“sValue1 := szValue1”注释掉,而改用那种方式?
就是因为使用sValue1 := szValue1报错(stack overflow),才用copymemory试试的
另外SetupGetSourceInfo其中的buffersize参数,大小应该是你前面计算的iSize。
试着把默认栈大小调高,看还会不会出错?
另外你的delphi版本是?
调高也不行我的delphi2010
strpas试过了。
前面说的,传给SetupGetSourceInfo的参数bufferSize是否已调过来?用你前面计算的isize。
d2009以上,char是两个字节的。另外一个api参数也要改为isize。
都改了,应该不是转换的问题,看下面代码注释。
function GetSections(AInf: HINF): TStrings;
var
szValue: PChar;
sValue: string;
i, iSize: Integer;
begin
Result := TStringList.Create;
iSize := MAX_PATH * SizeOf(Char);
szValue := StrAlloc(iSize);
try
ZeroMemory(szValue, iSize);
i := 0;
if SetupEnumInfSections(AInf, i, szValue, iSize, nil) then
repeat
if GetLastError = ERROR_NO_MORE_ITEMS then
Break;
//这里加上#0就不报错了,但其它地方不行(如调用SetupGetStringField之后),见鬼
// sValue := szValue + #0; sValue := StrPas(szValue);
OutputDebugString(PChar(sValue));//这里多分配一个Char也好了,又见鬼
// SetLength(sValue, lstrlen(szValue) + SizeOf(Char));
// CopyMemory(@sValue[1], szValue, lstrlen(szValue) * SizeOf(Char));//下面两句去掉,也不报错了,真见鬼了
if Result.IndexOf(sValue) = -1 then
Result.Add(sValue); Inc(i);
ZeroMemory(szValue, iSize);
until not SetupEnumInfSections(AInf, i, szValue, iSize, nil);
finally
StrDispose(szValue);
end;
end;
sValue := szValue + #0;
if Result.IndexOf(sValue) = -1 then
Result.Add(sValue); SetLength(sValue, lstrlen(szValue) + 2);
CopyMemory(@sValue[1], szValue, lstrlen(szValue) * SizeOf(Char));
if Result.IndexOf(sValue) = -1 then
Result.Add(sValue); sValue := StrPas(szValue);
OutputDebugString(PChar(sValue));
这三种都不报错了。
从你的测试代码看,多分配两个字节或 加一个0结尾或 调用StrPas 就没问题。说明直接赋值过程的代码有问题。可以的话,调出CPU view窗口,看里面的汇编码执行过程,看看他是怎么转换的。
调用strpas是有问题的,我说没问题的是我16楼说的那三种方式。跟踪了汇编代码,跟到getmem.inc里的sysgetmem,只是汇编不太懂
至于为什么会报错,暂时没弄明白。