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

解决方案 »

  1.   

    lz的意思应该是为什么溢出,不是翻译stack overflow
      

  2.   

    内存搞乱了。既然使用了string类型变量sValue1, sValue2;就不需要使用copymemory。而且你这样copymemory也不对。
    为什么你把“sValue1 := szValue1”注释掉,而改用那种方式?
      

  3.   


    就是因为使用sValue1 := szValue1报错(stack overflow),才用copymemory试试的
      

  4.   

    看看szValue2是什么,对不对?
    另外SetupGetSourceInfo其中的buffersize参数,大小应该是你前面计算的iSize。
      

  5.   

    没用。szValue2的值是对的,我只用outputdebugstring输出szvalue2的值完全能运行,赋值给svalue2就报错。
      

  6.   

    可能要先确认是不是字符问题。
    试着把默认栈大小调高,看还会不会出错?
    另外你的delphi版本是?
      

  7.   


    调高也不行我的delphi2010
    strpas试过了。
      

  8.   

    很可能是取出来的字符有问题。
    前面说的,传给SetupGetSourceInfo的参数bufferSize是否已调过来?用你前面计算的isize。
    d2009以上,char是两个字节的。另外一个api参数也要改为isize。
      

  9.   

    看方法内变量、参数声明,不会是变量分配过大问题。除非是Pchar转给string的数据有问题,导致转换异常。
      

  10.   


    都改了,应该不是转换的问题,看下面代码注释。
    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;
      

  11.   


          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));
    这三种都不报错了。
      

  12.   

    PChar赋值给String类型变量,delphi编译器会自动加代码转的。
    从你的测试代码看,多分配两个字节或 加一个0结尾或 调用StrPas 就没问题。说明直接赋值过程的代码有问题。可以的话,调出CPU view窗口,看里面的汇编码执行过程,看看他是怎么转换的。
      

  13.   


    调用strpas是有问题的,我说没问题的是我16楼说的那三种方式。跟踪了汇编代码,跟到getmem.inc里的sysgetmem,只是汇编不太懂
      

  14.   

    找到问题原因了,调用SetupGetInfFileList之后再调用上面的函数就会出错,不仅是上面的setupapi,其它setupapi中有ReturnBuffer参数的应该都会出问题。
    至于为什么会报错,暂时没弄明白。
      

  15.   

    调用RaiseLastWin32Error,看看提示什么讯息。
      

  16.   

    有时候还是出现stack overflow的问题,太奇怪了。