这种类型是C ++中的一个函数吗?

时间:2015-10-31 18:07:25

标签: c++ struct alias typedef

这是一个示例C ++代码块。我读了typedef,struct,enum和union的定义,但我仍然无法破译它。

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;
    

3 个答案:

答案 0 :(得分: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`
NTSTATUS (WINAPI * )(
    IN HANDLE FileHandle,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    OUT PVOID FileInformation,
    IN ULONG Length,
    IN FILE_INFORMATION_CLASS FileInformationClass
);

表示带有5个参数和返回类型NTSTATUS的函数的指针。

现在您可以使用此名称来声明指向此类型

的函数的指针
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,它们是Microsoft使用的宏,用于明确函数的每个参数的用途,无论是提供输入值还是用作输出参数

答案 1 :(得分:1)

这是函数指针的类型别名。

  

NTSTATUS(WINAPI * PFN_NTQUERYINFORMATIONFILE)是一个功能吗?为什么参数意味着在*之间?

不,这只是该类型的一部分。 *表示指针。这是一个指向具有WINAPI__stdcall)调用约定,NTSTATUS返回值和几个参数(HANDLEPIO_STATUS_BLOCK,{的函数的指针{1}},PVOIDULONG)。

  

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

这些是注释。 IN表示该函数仅使用参数进行输入,OUT表示该函数仅使用参数进行输出(它写入参数指向的参数)。 INOUT意味着函数读取和写入指向的内容。

Neil MacIntosh今年在CppCon上做了几个关于静态分析的演讲,在那里他谈到了这些注释是如何在微软代码库中出现的,以及它们如何帮助改进静态分析工具&#39;功能而不需要更多资源。但是,您可以使用实际类型提供相同的帮助,而不是编译为任何内容的注释,这是CppCoreGuidelines与GSL合作的方法。

  

为什么没有新的别名?

有。它是FILE_INFORMATION_CLASS。这只是C声明语法的一个怪癖,它在大多数情况下从内向外而不是从左向右读取。

  

我可以声明一个新的别名和一个指针别名吗?

不是我知道,不是。如果您使用PFN_NTQUERYINFORMATIONFILE完成相同的操作,typedef NTSTATUS(WINAPI func)(...), *func_pointer;将是func_pointer,而NTSTATUS*与问题相同,但不是指针。

这肯定适用于通过func生成的其他类型别名,例如问题中的typedef示例,它确实将struct声明为FILE_NAME_INFORMATION并且struct _FILE_NAME_INFORMATION作为PFILE_NAME_INFORMATIONstruct _FILE_NAME_INFORMATION*在那里强调宣布的各种名称。

答案 2 :(得分:0)

  1. 不,这是一个函数指针。中间的星号只是函数指针的正常语法的一部分 - WINAPI is just a macro

  2. 宏也是。 IN表示函数读取的参数(如const引用或value-by-value参数),而OUT表示用于“返回”参数的参数(如非const引用) )。

  3. 有一个:PFN_NTQUERYINFORMATIONFILE

  4. Yes.