2015-12-14 52 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'被重新定義了。請記住,你可以看到這個其他單位,我們不能。你看過嗎? –