我真的不明白为什么这个功能不起作用:
function GetNomRepertoireTemporaire:WideString;
var
PathLocal : array[0..MAX_PATH+1] of WideChar;
begin
Result := '';
if GetTempPath(SizeOf(PathLocal)-1, PathLocal)>0 then
begin
Result := PathLocal;
end;
end;
我称之为:
var
t : wideString;
initialization
t := GetNomRepertoireTemporaire;
我等了10秒,然后我得到AV at 0x000000 address 0000000
任何人都可以解释一下我做错了什么?
答案 0 :(得分:5)
您应该在代码中使用Length而不是SizeOf:
function GetNomRepertoireTemporaire:WideString;
var
PathLocal : array[0..MAX_PATH] of WideChar;
begin
Result := '';
if GetTempPath(Length(PathLocal), PathLocal)>0 then
begin
Result := PathLocal;
end;
end;
上面的代码假设您使用的是Unicode Delphi版本。正如David在评论中提到的,您可以更改函数以使其与Unicode和非Unicode Delphi兼容:
function GetNomRepertoireTemporaire:String;
var
PathLocal : array[0..MAX_PATH] of Char;
begin
Result := '';
if GetTempPath(Length(PathLocal), PathLocal)>0 then
begin
Result := PathLocal;
end;
end;
说明:GetTempPath
函数用它接收的整个缓冲区填充零。 OP代码设置无效的缓冲区大小(实际大小的两倍),因此该函数将PathLocal
变量后面的内存归零,从而产生AV。
答案 1 :(得分:4)
虽然这不能直接回答这个问题,但最好是调用内置的RTL方法IOUtils.TPath.GetTempPath
。
答案 2 :(得分:2)
如果您阅读API GetTempPath的帮助文件,您将在TCHAR中看到第一个参数是缓冲区的大小。 (即缓冲区中的字符数)
现在,您正在为函数提供缓冲区中的字节数,这是字符数的两倍。
像这样更改你的功能:
if GetTempPath(Length(PathLocal)-1, PathLocal)>0 then
答案 3 :(得分:0)
您可以使用普通字符串处理此问题,并完全避免使用array of char
。这是处理Windows api调用的好方法,因为您可以动态设置缓冲区的长度,SetLength
函数可以与AnsiStrings以及WideStrings一起使用。
function GetNomRepertoireTemporaire: String;
var
iSize: DWORD;
begin
SetLength(Result, MAX_PATH);
iSize := GetTempPath(MAX_PATH, PChar(Result));
// reduce buffer to the effectively used size. if the api call
// was successful, the terminating #0 is not included in iSize.
SetLength(Result, iSize);
end;
如果使用AnsiString或WideString,Delphi版本将决定。
答案 4 :(得分:-1)
我在阅读您的源代码时遇到了两件事。
第一个是对方法本身的调用。我发现函数GetTempPath的信息表明参数应该是Char(8位字符)。如果你真的需要宽字符串中的临时路径,你可能必须在调用GetTempPath之后将获得的路径转换为宽字符表示(只是一个猜测,因为我手边没有API文档)。
第二点是传递第二个参数。根据{{3}},您必须提供指向字符数组的指针。因此,对于您的示例,调用应该看起来像
if GetTempPath(MAX_PATH, @PathLocal) > 0 then
希望它有所帮助。