#Help understanding a typedef with function pointers

47 messages · Page 1 of 1 (latest)

white ibex
#

typedef void (WINAPI* FunctionPointer)();
What does this typedef do?

spark cedarBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

ancient socket
#

If you're just calling this pointer, you don't need to do anything. If you create your own function that it has to be able to point to, the function must be marked WINAPI too

white ibex
#

Ok, lets say I have a HelloWorld function from a custom DLL that has a HelloWorld function that makes a message box saying "Hello World". Why would I need to use "HelloWorldFunctionPointer HelloWorld = (HelloWorldFunctionPointer)pHelloWorld" before calling HelloWorld()?

ancient socket
#

What is pHelloWorld?

#

Are you LoadLibrarying that DLL?

white ibex
#

I can send the whole code

#

typedef void (WINAPI* HelloWorldFunctionPointer)();

void call() {
   
    HMODULE hModule = GetModuleHandleA("Path\\To\\Dll\\dll.dll");

    if (hModule == NULL) {
        hModule = LoadLibraryA("Path\\To\\Dll\\dll.dll");
    }

    PVOID pHelloWorld = GetProcAddress(hModule, "HelloWorld");

    HelloWorldFunctionPointer HelloWorld = (HelloWorldFunctionPointer)pHelloWorld;

    HelloWorld();

}

int main() {

    call(); 

    return 0;

}```
ancient socket
#

Are you asking why you can't pHelloWorld() directly?

white ibex
#

I'm mostly asking about the whole meaning of the HelloWorld declaration line

#

And why we have to use the HelloWorldFunctionPointer data type

ancient socket
#

To call a function, the compiler needs to know the parameter types and the return type

#

PVOID pHelloWorld = GetProcAddress(hModule, "HelloWorld"); doesn't provide any information about this

ancient socket
white ibex
#

So what this does is tell the compiler what to expect the function to return?

ancient socket
#

Basically yes

white ibex
#

So this data type is for custom functions, as normal ones are already declared and the compiler knows the parameters and return values?

ancient socket
#

You can use function pointers to point to normal functions too, but yes

#

Like,

int sum(int x, int y) {return x + y;}
int mul(int x, int y) {return x * y;}

bool x = ...;
int (*operation)(int, int) = x ? sum : mul;
int result = operation(10, 20);
white ibex
#

But then why do we need to use (HelloWorldFunctionPointer) before pHelloWorld?

ancient socket
#

That is a cast, to convert from one pointer type to another

white ibex
#

But isn't pHelloWorld just the address of the HelloWorld function?

ancient socket
#

Yes, but the type is different. It's similar to

int x = 42;
float *p = &x; // Doesn't compile without a cast
#

The compiler refuses to convert a pointer to a pointer to a different type to prevent you from shooting yourself in the foot

#

Pointer casts generally don't change the value of the pointer, just the type

white ibex
ancient socket
#

Sure, by spelling the type manually instead of using a typedef

white ibex
#

And what would that type be?

ancient socket
#

void (WINAPI*)()

#

void (WINAPI* HelloWorld)() = (void (WINAPI*)())pHelloWorld;

white ibex
#

So you're practically declaring a function that's a pointer of type WINAPI that returns void?

ancient socket
#

"function that is a pointer" makes no sense. HelloWorld is a pointer to "function taking no arguments and returning void", aka a pointer to void()

white ibex
#

Oh ok, that kind of makes sense

#

Are there any online tutorials on this topic?

ancient socket
#

¯_(ツ)_/¯

white ibex
#

Also, why would I need to cast the pointer from a normal pointer to "void (WINAPI*)()" type?

ancient socket
white ibex
#

In that example, you don't cast x to be some other type though, you only take it's address

ancient socket
#
int x = 42;
int *y = &x;
float *p = y; // Doesn't compile.
float *q = (float *)y;
white ibex
#

Ok, I see, thanks

spark cedarBOT
#

@white ibex Has your question been resolved? If so, type !solved :)

white ibex
#

Wait, I just tried running the program with "HelloWorldFunctionPointer HelloWorld = pHelloWorld;" and it worked somehow

ancient socket
#

Huh, true. It doesn't work in C++, but apparently C lets you convert void * to other pointer types without a cast

#

Was convinced it wouldn't convert to a function pointer, but apparently it does

white ibex
#

!solved

spark cedarBOT
#

Thank you and let us know if you have any more questions!

This thread is now set to auto-hide after an hour of inactivity