我正在Windows中实现一项服务。 VisualStudio 2012具有以下函数typedef:
typedef VOID WINAPI SERVICE_MAIN_FUNCTIONW (
DWORD dwNumServicesArgs,
LPWSTR *lpServiceArgVectors
);
还有一个函数指针typedef:
typedef VOID (WINAPI *LPSERVICE_MAIN_FUNCTIONW)(
DWORD dwNumServicesArgs,
LPWSTR *lpServiceArgVectors
);
如何使用typedef?
定义具有此函数签名的函数答案 0 :(得分:6)
引用当前的C ++标准(C ++ 11):
[dcl.fct] / 10
函数类型的typedef可用于声明函数,但不得用于定义函数(8.4)。 [实施例:
typedef void F(); F fv; // OK: equivalent to void fv(); F fv { } // ill-formed void fv() { } // OK: definition of fv
-end example]
也就是说,您可以使用typedef
声明但不能定义函数。您必须明确指定签名,请参阅Alex Farber的答案。
在某种程度上,您可以使用typedef
来“定义”该函数,但它涉及一些模板魔法。这是一个有趣的例子,表明你可以用它来定义一个函数。
// extra definitions for SSCCE
typedef unsigned int DWORD;
typedef wchar_t* LPWSTR;
#define VOID void
#define WINAPI
// function ptr
typedef VOID (WINAPI *LPSERVICE_MAIN_FUNCTIONW)(
DWORD dwNumServicesArgs,
LPWSTR *lpServiceArgVectors
);
// function typedef
typedef VOID WINAPI SERVICE_MAIN_FUNCTIONW (
DWORD dwNumServicesArgs,
LPWSTR *lpServiceArgVectors
);
template < typename... TT >
struct disassemble_funcptr
{};
template < typename Ret, typename... Args >
struct disassemble_funcptr < Ret(Args...) >
{
typedef Ret return_type;
static Ret Func(Args...)
{
/* your code here */
}
};
// using the typedef SERVICE_MAIN_FUNCTIONW to define the function
LPSERVICE_MAIN_FUNCTIONW my_func_ptr =
& disassemble_funcptr < SERVICE_MAIN_FUNCTIONW > :: Func;
int main()
{
LPWSTR str = nullptr;
my_func_ptr(42, &str);
}
答案 1 :(得分:1)
使用typedef
,函数不能定义 (或声明)。它必须以传统方式定义。 e.g。
void foo (type1 t1, type2 t2) // t1 and t2 are objects which can be ...
{ // ... visible only in conventional way
...
}
函数指针typedef可以声明函数指针,可以使用函数的地址指定:
typedef void (*PF)(type1, type2);
PF pf = &foo;
答案 2 :(得分:1)
您不需要(也不能)在函数定义中使用typedef。要创建服务主函数,只需写:
VOID WINAPI SvcMain( DWORD dwNumServicesArgs, LPWSTR *lpServiceArgVectors )
{
// ...
}
Windows内部使用 LPSERVICE_MAIN_FUNCTIONW
来调用每个服务起始点。通常,您需要函数指针typedef
来调用,而不是定义函数。
答案 3 :(得分:0)
使用C ++ 11,您可以使用具有空捕获列表的lambdas可转换为函数指针的事实来声明和定义与一个表达式中的函数typedef匹配的函数,例如:
using my_function_t = void(*)(int,int);
my_function_t add_function = [](int x, int y) { return x + y; };
答案 4 :(得分:0)
这可以通过反转尝试的方法来实现。
#define defLedClkFunc(name) void (name)(uint16_t led)
typedef defLedClkFunc(tLedClkFunction);
//********************************************************
//
// Declaration of first function
//
defLedClkFunc(ledClkEnable)
{
// Body of first function
} // ledClkEnable()
//********************************************************
//
// Declaration of second function
//
defLedClkFunc(ledClkDisable)
{
// Body of second function
} // ledClkDisable()
//
// Create an array of pointers to the functions
//
tLedClkFunction *myFuncs[] = {
ledClkEnable,
ledClkDisable,
};
现在您有了函数签名的单点定义,对签名的任何更改都会通过所有类型定义和函数声明传播。
我发现这对于定义函数集(例如中断处理程序、消息处理程序)非常有用。
此外,如果有人决定它们都应该有一些任意的前缀和/或后缀,则宏使得更改 *all 函数名称变得微不足道。只需使用标记粘贴作为宏定义的一部分,并在 name
周围粘贴所需的前缀/后缀。
您做需要记住创建的数据类型,以便操作指向函数的指针,但即使这样也可以通过少量的附加宏进行自动调整-魔法。