2015-10-31 36 views
2

這是一個示例C++代碼塊。我讀了typedef,struct,enum和union的定義,但是我仍然無法破譯這個。這是在C++中定義函數的類型嗎?

typedef NTSTATUS (WINAPI * PFN_NTQUERYINFORMATIONFILE)(
    IN HANDLE FileHandle, 
    OUT PIO_STATUS_BLOCK IoStatusBlock, 
    OUT PVOID FileInformation, 
    IN ULONG Length, 
    IN FILE_INFORMATION_CLASS FileInformationClass 
); 
  1. 是NTSTATUS(WINAPI * PFN_NTQUERYINFORMATIONFILE)的功能?爲什麼參數意味着有一個*之間?
  2. IN HANDLE FileHandle,OUT PIO_STATUS_BLOCK IoStatusBlock .. IN/OUT是什麼意思?
  3. 爲什麼沒有新的別名?
  4. 我可以聲明一個新的別名和一個指針別名嗎?在下面的示例中,我是否會使用PFILE_NAME_INFORMATION作爲指針名稱,並使用FILE_NAME_INFORMATION?

    typedef struct _FILE_NAME_INFORMATION { ... } 
    FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; 
    
+0

額外的空格,宏...你有一個IDE? –

+0

首先讓我說'_FILE_NAME_INFORMATION'是一個保留的標識符:您不能合法使用它。其次,'IN'和'OUT'不是C++關鍵字,所以我猜測*它們只是'#define's而已,並且只用作註釋。 –

+0

在你最後一個問題中,4.,你真的在​​問'struct'嗎?或者這只是一個類比,你實際上是在問函數指針嗎? – Downvoter

回答

1

這typedef聲明

typedef NTSTATUS (WINAPI * PFN_NTQUERYINFORMATIONFILE)(
    IN HANDLE FileHandle, 
    OUT PIO_STATUS_BLOCK IoStatusBlock, 
    OUT PVOID FileInformation, 
    IN ULONG Length, 
    IN FILE_INFORMATION_CLASS FileInformationClass 
); 

引入了alias named PFN_NTQUERYINFORMATIONFILE`對於代表一個指針與5組的參數和返回類型NTSTATUS下起作用的類型

NTSTATUS (WINAPI *)(
    IN HANDLE FileHandle, 
    OUT PIO_STATUS_BLOCK IoStatusBlock, 
    OUT PVOID FileInformation, 
    IN ULONG Length, 
    IN FILE_INFORMATION_CLASS FileInformationClass 
); 

現在你可以使用這個名稱的指針聲明這種類型的函數

PFN_NTQUERYINFORMATIONFILE ptr; 

你可以得到相同的方式如下,看起來更加清晰

using PFN_NTQUERYINFORMATIONFILE = 
    NTSTATUS (WINAPI *)(
     IN HANDLE FileHandle, 
     OUT PIO_STATUS_BLOCK IoStatusBlock, 
     OUT PVOID FileInformation, 
     IN ULONG Length, 
     IN FILE_INFORMATION_CLASS FileInformationClass 
    ); 

還要考慮以下幾個簡單的示例

#include <iostream> 

int sum(int x, int y) 
{ 
    return x + y; 
} 

int product(int x, int y) 
{ 
    return x * y; 
} 

int division(int x, int y) 
{ 
    return x/y; 
} 

typedef int (*fp)(int, int); 

int main() 
{ 
    for (fp f : { sum, product, division }) std::cout << f(10, 2) << std::endl; 
} 

輸出爲

12 
20 
5 

考慮到當函數名在表達式中使用時,函數名會隱式轉換爲指向函數的指針。

因此,例如,從上面的示範程序的功能,這種說法是有效

std::cout << (***/* replace the comment with as many asterisks as you like */****sum)(10, 20) << std::endl; 

所以,如果你相應的報酬在程序輸入的符號數,那麼你可以使用這一招用函數調用。

(****************************************************sum)(10, 20); 

這僅受限於編譯器限制。

至於INOUT那麼它們就是微軟使用的宏,用於明確函數的每個參數是用來做什麼的,是提供輸入值還是用作輸出參數。

1

這是一個函數指針的類型別名。

是NTSTATUS(WINAPI * PFN_NTQUERYERYFORMATIONFILE)函數嗎?爲什麼參數意味着有一個*之間?

不,這只是該類型的一部分。 *表示一個指針。這是一個指向具有WINAPI__stdcall)調用約定,NTSTATUS返回值和幾個參數(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONGFILE_INFORMATION_CLASS)的函數的指針。

IN HANDLE FileHandle,OUT PIO_STATUS_BLOCK IoStatusBlock .. IN/OUT是什麼意思?

這些是註釋。 IN意味着該函數僅將該參數用於僅輸入,OUT表示該函數僅將該參數用於輸出(它將寫入參數指向的內容)。 INOUT意味着該函數讀取和寫入正在指向的內容。

Neil MacIntosh實際上在CppCon上做了一些關於靜態分析的演講,他談到了如何在Microsoft代碼庫中使用這些註釋,以及他們如何幫助改進靜態分析工具的功能而不需要更多資源。但是,您可以對實際類型提供相同的幫助,而不是將註釋編譯爲空白,這是CppCoreGuidelines項目與GSL一起採用的方法。

爲什麼沒有新的別名?

有。這是PFN_NTQUERYINFORMATIONFILE。這只是C聲明語法的一個怪癖,它大部分是從內向外讀取而不是從左向右讀取。

我可以聲明一個新的別名和一個指針別名嗎?

不是我知道的,沒有。假如你做同樣的伎倆與typedef NTSTATUS(WINAPI func)(...), *func_pointer;func_pointer將是一個NTSTATUS*func是相同的問題,而不是一個指針。

這當然適用於通過typedef,生產其他類型的別名,不過,如在的問題,這確實申報FILE_NAME_INFORMATION作爲struct _FILE_NAME_INFORMATIONPFILE_NAME_INFORMATIONstruct _FILE_NAME_INFORMATION*,在struct在那裏強調不同類型的struct例子名字被宣佈。

0
  1. 不,它是一個函數指針。中間的星號只是函數指針的正常語法的一部分 - WINAPIis just a macro

  2. 宏太。 IN表示函數讀取的參數(如const引用或值複製參數),而OUT引用用於「返回」參數的參數(如非const引用)。有一個:PFN_NTQUERYINFORMATIONFILE

  3. Yes.

+0

我不認爲這是OP在#4問的問題。我相信問題是,是否有辦法在單個語句中聲明函數類型的別名和指向同一函數類型的指針的別名,就像如何使用其他類型別名(如結構)一樣。 – chris

+0

@chris所以你的意思是這只是一個比喻?可能會,但我沒有看到任何暗示表明這一點。 「在下面的例子中」說服了我。 – Downvoter

+0

這是我對這個問題的解釋。 OP可以肯定地澄清。 – chris

相關問題