2015-12-14 53 views
0

我使用这个功能来获得用户文件夹:德尔福的SHGetFolderPath和空结束的字符串

function LocalAppDataPath : string; 
const 
    SHGFP_TYPE_CURRENT = 0; 
var 
    path: array [0..MaxChar] of char; 
begin 
    SHGetFolderPath(0,CSIDL_LOCAL_APPDATA,0,SHGFP_TYPE_CURRENT,@path[0]); 
    Result := StrPas(path); 
end; 

这是伟大的工作。 但我把这个lib添加到我的项目后:OpenJpeg 从这个函数返回的值是:C.这似乎是由于某些原因,“路径”数组中的每个字符后有#0,并因此返回字符串在开始时被截断。

当我删除:OpenJpeg从我使用它一切正常。

任何想法,为什么会发生?

+0

的SHGetFolderPath已被弃用,你可以尝试Unicode和ANSI名字 \t'SHGetFolderPathW()'(** **的Unicode)和'SHGetFolderPathA()'(** ** ANSI)。我们也看不到你的delphi版本。 –

+1

@ moskito-X:'ShGetFolderPath'映射到可以是W或A的版本,根据版本的Delphi,即无论是“的Unicode”与否。它不被弃用。但显然,OpenJPeg利用自己的导入来解决问题。 –

回答

7

OpenJpeg单元的最顶部是发现这样的代码:在Unicode的Delphi使用时

type 
    Char = AnsiChar; 

此单元因此是有毒的。当你在代码中使用Char你期待一个WideChar但是这个邪恶的类型别名混淆你。

我的建议是修改库删除该类型别名与AnsiChar替换每次使用的Char

如果您不想这样做,您可以完全限定CharSystem.Char,或在代码中明确使用WideChar。但是,正如我所说,这个单位是有毒的,而且它确实需要补救。

如果启用Typed-Checked Pointers编译器选项,编译器将使用由@地址运算符时传递PAnsiChar给一个函数期待一个PWideChar,反之亦然,阻止你。如果可能,最好在编译时找到你的错误。

您可以代替@path[0]通过path简化代码。

请不要使用StrPas。它一直被弃用。你可以简单地写

Result := path; 

该数组是一个比所需的字符长。也就是说,假设MaxChar是我认为的。无论如何,阵列应该是

path: array [0..MAX_PATH-1] of char; 

您也无法对API调用执行任何错误检查。请按照文档中的描述检查错误。

+2

你不需要'@'地址操作符来开始。用'path'替换'@path [0]',编译器仍然会检测到任何类型的不匹配错误。 –

+0

感谢您对这个问题的完全合理解释。但是,由于某种原因,它仍然不起作用。我将这个函数改为:ShlObj。SHGetFolderPath(0,CSIDL_LOCAL_APPDATA,0,SHGFP_TYPE_CURRENT,@path);. “路径”之前的“@”仍然需要,返回的数组仍然存在#0问题。 – bashan

+0

您启用了类型选中的指针?也许实际发生的是'char'被重新定义了。请记住,你可以看到这个其他单位,我们不能。你看过吗? –