簡體   English   中英

有效地為不同的Windows版本使用不同的API

[英]Using different API for different Windows versions efficiently

我面臨着在可用的情況下使用新的Windows運行時功能的需要,並且回歸到新的運行時功能不存在的情況。

代碼路徑對性能至關重要。 如果平台(Windows 8 / Windows Server 2012)提供它,我需要調用GetSystemTimePreciseAsFileTime如果新版本不存在,則返回GetSystemTimeAsFileTime

我知道我可以使用LoadLibraryGetProcAddress加載GetSystemTimePreciseAsFileTime ,如果失敗,則回退到GetSystemTimeAsFileTime 我擔心通過另一層間接性來調用某些東西作為性能的關鍵性能影響。

是否有任何內置機制來延遲加載符號,而不是整個DLL? 所以,我可以在啟動測試的Windows版本和調用使用功能GetSystemTimePreciseAsFileTime上Win8的,否則調用使用了一個GetSystemTimeAsFileTime ,而不會導致整個可執行文件失敗,在舊版本的Windows鏈接錯誤?

或者我應該停止擔心並使用GetProcAddress

正如對問題的各種評論所說, GetProcAddress()的成本很低。 通過函數指針調用函數的成本也接近於零。

但是,讓我們說我們正在超級批判地工作。 我們觀察到您要調用的兩個函數具有簽名

VOID WINAPI GetSystemTimePreciseAsFileTime(LPFILETIME lpSystemTimeAsFileTime);
void WINAPI GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime);

也就是說,它們具有幾乎相同的簽名; 唯一的區別是VOID奇怪返回類型...... MSDN所說的只是一個擴展為void的宏 ,所以它們完全相同。

這是什么意思? 這意味着您可以使用單個函數指針變量,在程序開始時初始化一次,如下所示:

// global scope
VOID (*WINAPI myGetSystemTime)(LPFILETIME);

// in your initalization code
FARPROC fp;
myGetSystemTime = GetSystemTimeAsFileTime;
if (/* LoadLibraryW(L"kernel32.dll") worked */) {
    fp = GetProcAddress(/* library handle */, "GetSystemTimePreciseAsFileTime");
    if (fp != NULL)
        myGetSystemTime = (VOID (*WINAPI)(LPFILETIME)) fp;
}
// and don't worry about errors from LoadLibraryW() or GetProcAddress() since we want to use the fallback; you may log a warning if you so choose

然后你需要做的就是在需要選擇性地調用函數時調用(*myGetSystemTime)(&time) 沒有條件分支或不斷輪詢DLL,並且應該沒有可衡量的性能影響。

我認為andlabs的回答可能是正確的; 通過指針調用函數的性能損失不太可能很大。 另一方面,它確實需要額外的RAM往返(或者導致指針占用緩存中可能更好用的一行),所以它並不是絕對確定的。

如果分析表明您確實遇到了問題,請考慮將性能關鍵代碼放入DLL中。 有兩個版本的DLL,每個版本一個。 安裝應用程序后,將適當的版本放在適當的位置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM