Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining a function using a function typedef in C++

I am implementing a service in Windows. VisualStudio 2012 has the following function typedef:

typedef VOID WINAPI SERVICE_MAIN_FUNCTIONW (
    DWORD dwNumServicesArgs,
    LPWSTR *lpServiceArgVectors
);

There is also a function pointer typedef:

typedef VOID (WINAPI *LPSERVICE_MAIN_FUNCTIONW)(
    DWORD   dwNumServicesArgs,
    LPWSTR  *lpServiceArgVectors
);

How do I define a function with this function signature, using the typedef?

like image 210
chowey Avatar asked Dec 21 '22 06:12

chowey


1 Answers

Quoting the current C++ Standard (C++11):

[dcl.fct]/10

A typedef of function type may be used to declare a function but shall not be used to define a function (8.4). [Example:

typedef void F();
F fv;             // OK: equivalent to void fv();
F fv { }          // ill-formed
void fv() { }     // OK: definition of fv

—end example ]

That is, you can declare but not define the function using that typedef. You have to specify the signature explicitly, see Alex Farber's answer.


To some extent, you can use the typedef to "define" the function, but it involves some template magic. It's a just-for-fun example to show that you can actually use it to define a function.

// 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);
}
like image 108
dyp Avatar answered Dec 24 '22 00:12

dyp