Handmade Hero»Forums»Game
19 posts
Why platform-specific functions are passed by pointer?
Edited by Terans on Reason: Initial post
In the non-specific code, Casey uses various pointers to functions that the platform layer must set. Why don't directly use classic functions, and directly call them? It's what happens with the "DEBUG*" functions, they are not passed as pointer, but called directly by the game, so why?
Mārtiņš Možeiko
2559 posts / 2 projects
Why platform-specific functions are passed by pointer?
It could be done that way. Just export platform functions from main exe file and in game dll use them.

But there is a disadvantage - you cannot choose which platform function to use depending on some condition. For example, you might want to substitute actual function with "no-operation" - empty function. If game dll directly links to exe and calls function directly, you cannot override (or it is very hard), or it requires complex conditions in every single function. Passing function pointer this makes it trivial - just pass different function pointer.

More importantly this is disadvnatage when renderer was split of game/platform layers into separate dll. This way game does not care is it rendered using OpenGL, Direct3D or software renderer. Ability to pass different function pointers for renderer makes platform to choose whichever renderer to use and game just uses it without knowing what it uses.


Dan Zaidan
45 posts / 1 project
Game programmer. Creator of Eliosi's Hunt. I share the love I have for making games on my Youtube channel: http://youtube.com/danzaidan
Why platform-specific functions are passed by pointer?
Whaaaaat?

You are actually saying that I don't have to pass a ton of pointers to the dll? That is sweet! :D

I tried messing around with __declspec(dllexport/dllimport) but I can't get pass the linker...
Can you give me a pointer as to how that can be done? :)
Mārtiņš Možeiko
2559 posts / 2 projects
Why platform-specific functions are passed by pointer?
Edited by Mārtiņš Možeiko on
main.c:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include <windows.h>
#include <stdio.h>

__declspec(dllexport) void main_fun()
{
    printf("Hello from main.exe\n");
}

int main()
{
    HMODULE m = LoadLibraryA("library.dll");
    void (*fun)() = (void*)GetProcAddress(m, "library_fun");

    printf("Calling library_fun\n");
    fun();
    printf("Back in main()\n");
}


library.c:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#include <stdio.h>

void main_fun();

__declspec(dllexport) void library_fun()
{
    printf("Hello from library.dll\n");
    main_fun();
    printf("Finishing library_fun()\n");
}


Compiling:
1
2
cl main.c
cl /LD library.c main.lib


Output of running main.exe:
1
2
3
4
5
Calling library_fun
Hello from library.dll
Hello from main.exe
Finishing library_fun()
Back in main()


Note that __declspec(dllexport) or dllimport is not really needed. That's just one way how to export symbols. You can instead do /EXPORT or /DEF in linker arguments. It's your choice. They all do same thing.
Dan Zaidan
45 posts / 1 project
Game programmer. Creator of Eliosi's Hunt. I share the love I have for making games on my Youtube channel: http://youtube.com/danzaidan
Why platform-specific functions are passed by pointer?
That's awesome!
Thanks so much for the in-depth explanation! :)
poe
5 posts
Why platform-specific functions are passed by pointer?
Thank you for a really awesome answer! :)