这是一个示例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
);
我可以声明一个新的别名和一个指针别名吗?在下面的示例中,我会使用PFILE_NAME_INFORMATION指针名称和FILE_NAME_INFORMATION吗?
typedef struct _FILE_NAME_INFORMATION { ... }
FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
答案 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 );
这仅受编译器限制的限制。
对于IN
和OUT
,它们是Microsoft使用的宏,用于明确函数的每个参数的用途,无论是提供输入值还是用作输出参数
答案 1 :(得分:1)
这是函数指针的类型别名。
NTSTATUS(WINAPI * PFN_NTQUERYINFORMATIONFILE)是一个功能吗?为什么参数意味着在*之间?
不,这只是该类型的一部分。 *
表示指针。这是一个指向具有WINAPI
(__stdcall
)调用约定,NTSTATUS
返回值和几个参数(HANDLE
,PIO_STATUS_BLOCK
,{的函数的指针{1}},PVOID
和ULONG
)。
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_INFORMATION
,struct _FILE_NAME_INFORMATION*
在那里强调宣布的各种名称。
答案 2 :(得分:0)
不,这是一个函数指针。中间的星号只是函数指针的正常语法的一部分 - WINAPI
is just a macro。
宏也是。 IN
表示函数读取的参数(如const引用或value-by-value参数),而OUT
表示用于“返回”参数的参数(如非const引用) )。
有一个:PFN_NTQUERYINFORMATIONFILE
。