dadas dasdas
dadas dasdas

Reputation: 97

Explain this situation of pointers

I'm learning pointers and I get lost in this code:

    template<typename T>
    inline T export(const char *dll, const char *name)
    {
        return (T) ((void *(*)(const char *, const char *))GetProcAddress(GetModuleHandleA(dll), name));
    }

To be more exact, I don't understand the part where it does some weird conversion of void pointer(s). Even more exact problem: What does *(*) do and when can you use it?

Upvotes: 3

Views: 82

Answers (4)

NickLamp
NickLamp

Reputation: 862

(void *(*)(const char *, const char *) means you are casting the following function to a function pointer (*) that returns a void pointer void * and takes two constant char pointers (const char *, const char *) as parameters

Such a function pointer by itself might be declared as

(void *(*foo)(const char *, const char *);

Upvotes: 2

axiac
axiac

Reputation: 72226

(T) ((void *(*)(const char *, const char *))GetProcAddress(...)

The value returned by GetProcAddress() is converted twice: once to a pointer to a function that receives two arguments of type const char * and returns a void * then the result is converted to type T

The C/C++ variable and type declarations are decoded from inside out. Start with the variable or type name, check on the right for () (function) or [] (array) then on the left for the type of the values returned by the function or contained in the array but without crossing the parentheses. Remove the inner set of parentheses and repeat.

For example:

void *(*p)(const char *, const char *)

p is (nothing on the right, not crossing the parentheses) a pointer (* on the left) to (escape one level of parentheses) a function having two arguments of type const char * ((...) on the right) that returns void * (on the left).

To recap, p is a pointer to a function that receives two const char * arguments and returns void *.

p above is a variable. If the entire declaration is prefixed with typedef, p becomes the definition of a new type.

Without p (and without typedef) it is an anonymous type that is used in the question for type casting: by placing it inside parentheses, the value returned by GetProcAddress() is converted to the type described above. The (T) in front of it forces another conversion to type T.


In the posted expression, the complex type described above is enclosed in two pairs of parentheses. Only one pair is needed. The other one can be safely removed.

Upvotes: 1

molbdnilo
molbdnilo

Reputation: 66371

The (*) says "this is a function pointer".
The thing to the right, (const char *, const char *), is the parameter types.
The thing to the left, void *, is the return type.

So it casts the result from GetProcAddress to the function pointer type void *(*)(const char *, const char *).

The cast is completely pointless as the result is immediately cast to the type T provided by the caller.

The function also has one of the more confusing names ever invented, as it does the opposite of exporting.

Upvotes: 1

Rakete1111
Rakete1111

Reputation: 48948

void *(*)(const char *, const char *) is a function pointer which returns void* and takes as arguments 2 const char *.

void *   (*)       (const char *, const char *)
^^^^^^    ^        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^      
return  pointer     signature
value

So basically, this casts the returned value of GetProcAddress to void *(*)(const char *, const char *) and then casts it to T

Upvotes: 1

Related Questions