2011-04-16 52 views
3

MSDN上,我注意到了VerQueryValue函數如下:瞭解VerQueryValue

lplpBuffer [出]
LPVOID
此方法返回時,包含一個指針的地址在緩衝區中的請求的版本信息由pBlock指向。 內存指向lplpBuffer被釋放時,相關pBlock內存freed._

系統如何知道因爲pBlock由主叫方分配時pBlock被釋放?

我使用以下代碼:

UINT reqSize = ::GetSystemDirectoryW(nullptr, 1); 

std::vector<wchar_t> winDirectory (reqSize, 0); 

UINT retVal = ::GetSystemDirectoryW(&winDirectory[0], reqSize); 

std::wstring filePath(winDirectory.begin(), winDirectory.end()-1); 

filePath.append(L"\\kernel32.dll"); 

DWORD bufSize = ::GetFileVersionInfoSizeW(
    filePath.c_str(), 
    nullptr); 

std::vector<BYTE> fileInfo (bufSize, 0); 

::GetFileVersionInfoW(
    filePath.c_str(), 
    0, 
    bufSize, 
    &fileInfo[0]); 

UINT size = 0; 

VS_FIXEDFILEINFO * ptr = nullptr; 

BOOL error = ::VerQueryValueW(
    &fileInfo[0], 
    L"\\", 
    reinterpret_cast<LPVOID*>(&ptr), 
    &size); 

回答

4

VerQueryValue指針返回到的地方,你分配(GetFileVersionInfoSize返回一個塊,其足夠大以包含ANSI要求Unicode轉換等整個版本資源+任何空間的大小)

的存儲器中的初始塊內
2

GetFileVersionInfo將數據複製到提供的緩衝區。由於該數據的格式沒有現成/文檔,您需要使用輔助函數VerQueryValue內檢索指向特定條目填入緩衝區GetFileVersionInfo

的方式MS記載,「指針返回由VerQueryValue不從任何地方分配 - 它只是指向另一個緩衝區內的某個地方「有點混淆。

+0

這聽起來像他們說第二個指針指向已經分配的內存塊。所以只有一塊分配的內存被釋放。 – 2011-04-16 17:44:17

+0

@Steve Wellens:作爲(希望)所有內存都是以某種方式分配的,這是真的。 MSDN中的描述並沒有真正說明「已經分配的內存」實際上是用戶提供給GetFileVersionInfo的早期緩衝區 – Erik 2011-04-16 18:09:23

+0

因爲它是直C而不是C++,所以它們不能在析構函數中完成。除非他們有其他魔法繼續,我猜/假設/假設;)他們正在使用realloc來拉伸原始緩衝區,然後使成員指針指向新的空間。所以當原始記憶被釋放時......它全部被釋放。 – 2011-04-16 22:57:42

3

至少在某些情況下,VerQueryValue執行版本數據轉換(例如,Unicode版本爲GetFileVersionInfo,但使用ASCII版本VerQueryValue時,Unicode轉換爲ASCII轉換)。明顯計算出足夠大的緩衝區大小以容納轉換後的數據。