Platform-Agnostic Windowing library











up vote
1
down vote

favorite












I am making a C library that abstracts window creation with support for the new Vulkan API under a unified API;
I have a github repository that you check out.



main.c



#include "vkwf.h"

int main()
{
VKWFWindow* window = VKWFCreateWindow("Test Window", 800, 600);

while (!VKWFWindowShouldClose(window))
{
VKWFWindowUpdate(window);
}

free(window);

return 0;
}


The way I am handling this is creating a general vkwf.h file, that includes a list of functions, like this:



vkwf.h



#pragma once

#ifdef __cplusplus
extern "C" {
#endif

#ifdef VKWF_PLATFORM_WINDOWS
#include "win32_window.h"
#elif VKWF_PLATFORM_MACOS
#include "macos_window.h"
#elif VKWF_PLATFORM_LINUX
#include "linux_window.h"
#endif

VKWFWindow* VKWFCreateWindow(const char* title, int width, int height)
{
return VKWFPlatformCreateWindow(title, width, height);
}

VKWFBool VKWFWindowShouldClose(VKWFWindow* window)
{
return VKWFPlatformWindowShouldClose(window);
}

void VKWFWindowUpdate(VKWFWindow* window)
{
VKWFPlatformUpdate(window);
}

void VKWFDestroyWindow(VKWFWindow* window)
{
VKWFPlatformDestroyWindow(window);
}

#ifdef __cplusplus
}
#endif


All VKWFPlatformX() functions are functions that get defined by the platform_window.h files, like this:



win32_window.h (short)



#define VKWFPlatformCreateWindow(title,width,height) VKWFWin32CreateWindow(title,width,height)
#define VKWFPlatformWindowShouldClose(window) VKWFWin32WindowShouldClose(window)
#define VKWFPlatformUpdate(window) VKWFWin32Update(window)
#define VKWFPlatformDestroyWindow(window) VKWFWin32DestroyWindow(window)


Does this look like a good approach?
Are there any drawbacks, or things that i could improve?










share|improve this question







New contributor




Gabriele Vierti is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
























    up vote
    1
    down vote

    favorite












    I am making a C library that abstracts window creation with support for the new Vulkan API under a unified API;
    I have a github repository that you check out.



    main.c



    #include "vkwf.h"

    int main()
    {
    VKWFWindow* window = VKWFCreateWindow("Test Window", 800, 600);

    while (!VKWFWindowShouldClose(window))
    {
    VKWFWindowUpdate(window);
    }

    free(window);

    return 0;
    }


    The way I am handling this is creating a general vkwf.h file, that includes a list of functions, like this:



    vkwf.h



    #pragma once

    #ifdef __cplusplus
    extern "C" {
    #endif

    #ifdef VKWF_PLATFORM_WINDOWS
    #include "win32_window.h"
    #elif VKWF_PLATFORM_MACOS
    #include "macos_window.h"
    #elif VKWF_PLATFORM_LINUX
    #include "linux_window.h"
    #endif

    VKWFWindow* VKWFCreateWindow(const char* title, int width, int height)
    {
    return VKWFPlatformCreateWindow(title, width, height);
    }

    VKWFBool VKWFWindowShouldClose(VKWFWindow* window)
    {
    return VKWFPlatformWindowShouldClose(window);
    }

    void VKWFWindowUpdate(VKWFWindow* window)
    {
    VKWFPlatformUpdate(window);
    }

    void VKWFDestroyWindow(VKWFWindow* window)
    {
    VKWFPlatformDestroyWindow(window);
    }

    #ifdef __cplusplus
    }
    #endif


    All VKWFPlatformX() functions are functions that get defined by the platform_window.h files, like this:



    win32_window.h (short)



    #define VKWFPlatformCreateWindow(title,width,height) VKWFWin32CreateWindow(title,width,height)
    #define VKWFPlatformWindowShouldClose(window) VKWFWin32WindowShouldClose(window)
    #define VKWFPlatformUpdate(window) VKWFWin32Update(window)
    #define VKWFPlatformDestroyWindow(window) VKWFWin32DestroyWindow(window)


    Does this look like a good approach?
    Are there any drawbacks, or things that i could improve?










    share|improve this question







    New contributor




    Gabriele Vierti is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






















      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I am making a C library that abstracts window creation with support for the new Vulkan API under a unified API;
      I have a github repository that you check out.



      main.c



      #include "vkwf.h"

      int main()
      {
      VKWFWindow* window = VKWFCreateWindow("Test Window", 800, 600);

      while (!VKWFWindowShouldClose(window))
      {
      VKWFWindowUpdate(window);
      }

      free(window);

      return 0;
      }


      The way I am handling this is creating a general vkwf.h file, that includes a list of functions, like this:



      vkwf.h



      #pragma once

      #ifdef __cplusplus
      extern "C" {
      #endif

      #ifdef VKWF_PLATFORM_WINDOWS
      #include "win32_window.h"
      #elif VKWF_PLATFORM_MACOS
      #include "macos_window.h"
      #elif VKWF_PLATFORM_LINUX
      #include "linux_window.h"
      #endif

      VKWFWindow* VKWFCreateWindow(const char* title, int width, int height)
      {
      return VKWFPlatformCreateWindow(title, width, height);
      }

      VKWFBool VKWFWindowShouldClose(VKWFWindow* window)
      {
      return VKWFPlatformWindowShouldClose(window);
      }

      void VKWFWindowUpdate(VKWFWindow* window)
      {
      VKWFPlatformUpdate(window);
      }

      void VKWFDestroyWindow(VKWFWindow* window)
      {
      VKWFPlatformDestroyWindow(window);
      }

      #ifdef __cplusplus
      }
      #endif


      All VKWFPlatformX() functions are functions that get defined by the platform_window.h files, like this:



      win32_window.h (short)



      #define VKWFPlatformCreateWindow(title,width,height) VKWFWin32CreateWindow(title,width,height)
      #define VKWFPlatformWindowShouldClose(window) VKWFWin32WindowShouldClose(window)
      #define VKWFPlatformUpdate(window) VKWFWin32Update(window)
      #define VKWFPlatformDestroyWindow(window) VKWFWin32DestroyWindow(window)


      Does this look like a good approach?
      Are there any drawbacks, or things that i could improve?










      share|improve this question







      New contributor




      Gabriele Vierti is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      I am making a C library that abstracts window creation with support for the new Vulkan API under a unified API;
      I have a github repository that you check out.



      main.c



      #include "vkwf.h"

      int main()
      {
      VKWFWindow* window = VKWFCreateWindow("Test Window", 800, 600);

      while (!VKWFWindowShouldClose(window))
      {
      VKWFWindowUpdate(window);
      }

      free(window);

      return 0;
      }


      The way I am handling this is creating a general vkwf.h file, that includes a list of functions, like this:



      vkwf.h



      #pragma once

      #ifdef __cplusplus
      extern "C" {
      #endif

      #ifdef VKWF_PLATFORM_WINDOWS
      #include "win32_window.h"
      #elif VKWF_PLATFORM_MACOS
      #include "macos_window.h"
      #elif VKWF_PLATFORM_LINUX
      #include "linux_window.h"
      #endif

      VKWFWindow* VKWFCreateWindow(const char* title, int width, int height)
      {
      return VKWFPlatformCreateWindow(title, width, height);
      }

      VKWFBool VKWFWindowShouldClose(VKWFWindow* window)
      {
      return VKWFPlatformWindowShouldClose(window);
      }

      void VKWFWindowUpdate(VKWFWindow* window)
      {
      VKWFPlatformUpdate(window);
      }

      void VKWFDestroyWindow(VKWFWindow* window)
      {
      VKWFPlatformDestroyWindow(window);
      }

      #ifdef __cplusplus
      }
      #endif


      All VKWFPlatformX() functions are functions that get defined by the platform_window.h files, like this:



      win32_window.h (short)



      #define VKWFPlatformCreateWindow(title,width,height) VKWFWin32CreateWindow(title,width,height)
      #define VKWFPlatformWindowShouldClose(window) VKWFWin32WindowShouldClose(window)
      #define VKWFPlatformUpdate(window) VKWFWin32Update(window)
      #define VKWFPlatformDestroyWindow(window) VKWFWin32DestroyWindow(window)


      Does this look like a good approach?
      Are there any drawbacks, or things that i could improve?







      c






      share|improve this question







      New contributor




      Gabriele Vierti is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question







      New contributor




      Gabriele Vierti is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question






      New contributor




      Gabriele Vierti is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 4 hours ago









      Gabriele Vierti

      1063




      1063




      New contributor




      Gabriele Vierti is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      Gabriele Vierti is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      Gabriele Vierti is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          1
          down vote













          I wouldn't use #define macros. They expose the internal naming convention of your OS dependent functions to the world. Once you send out your library to others [as a shared library], you can never change your internal OS dependent names. The important thing is that public facing names be functions.



          For example, if two systems used gcc and created ELF binaries that only called your library functions, could you compile on (e.g.) FreeBSD and that binary would run without rebuild on linux. There are other issues with doing this, so it [probably] isn't practical, but, it's something to think about.



          A better way [what I've done when faced with a similar problem] is to put the OS dependent code in a .c and add static to the definitions.



          The public functions just call the static ones. The static function names are the same, regardless of platform



          The optimizer will either inline the static OS dependent function or will use tail call optimization. So, it's just as fast as macros but a lot cleaner.



          Side note: Your naming convention is a bit [MS] Windows centric (i.e. camel hump case). I prefer snake case (e.g. see GTK, etc.). For an example, see the bottom.





          vkwh.h:



          #pragma once

          #ifdef __cplusplus
          extern "C" {
          #endif

          VKWFWindow* VKWFCreateWindow(const char* title, int width, int height);
          VKWFBool VKWFWindowShouldClose(VKWFWindow* window);
          void VKWFWindowUpdate(VKWFWindow* window);
          void VKWFDestroyWindow(VKWFWindow* window);

          #ifdef __cplusplus
          }
          #endif




          vkwf.c:



          #include "vkwf.h"

          #ifdef VKWF_PLATFORM_WINDOWS
          #include "win32_window.c"
          #elif VKWF_PLATFORM_MACOS
          #include "macos_window.c"
          #elif VKWF_PLATFORM_LINUX
          #include "linux_window.c"
          #endif

          VKWFWindow* VKWFCreateWindow(const char* title, int width, int height)
          {
          return VKWFPlatformCreateWindow(title, width, height);
          }

          VKWFBool VKWFWindowShouldClose(VKWFWindow* window)
          {
          return VKWFPlatformWindowShouldClose(window);
          }

          void VKWFWindowUpdate(VKWFWindow* window)
          {
          VKWFPlatformUpdate(window);
          }

          void VKWFDestroyWindow(VKWFWindow* window)
          {
          VKWFPlatformDestroyWindow(window);
          }




          win32_window.c:



          #include "vkwf.h"

          static VKWFWindow*
          VKWFPlatformCreateWindow(const char* title, int width, int height)
          {
          // ...
          }

          static VKWFBool
          VKWFPlatformWindowShouldClose(VKWFWindow* window)
          {
          // ...
          }

          static void
          VKWFPlatformWindowUpdate(VKWFWindow* window)
          {
          // ...
          }

          static void
          VKWFPlatformDestroyWindow(VKWFWindow* window)
          {
          // ...
          }




          Here's an example of the snake case for the public functions. Note that since the platform specific functions are static, then can use shorter prefixes:



          #include "vkwf.h"

          #ifdef VKWF_PLATFORM_WINDOWS
          #include "win32_window.c"
          #elif VKWF_PLATFORM_MACOS
          #include "macos_window.c"
          #elif VKWF_PLATFORM_LINUX
          #include "linux_window.c"
          #endif

          VKWFWindow* VKWF_create_window(const char* title, int width, int height)
          {
          return platform_create_window(title, width, height);
          }

          VKWFBool VKWF_window_should_close(VKWFWindow* window)
          {
          return platform_window_should_close(window);
          }

          void VKWF_window_update(VKWFWindow* window)
          {
          platform_update(window);
          }

          void VKWF_destroy_window(VKWFWindow* window)
          {
          platform_destroy_window(window);
          }





          share|improve this answer























            Your Answer





            StackExchange.ifUsing("editor", function () {
            return StackExchange.using("mathjaxEditing", function () {
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            });
            });
            }, "mathjax-editing");

            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "196"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });






            Gabriele Vierti is a new contributor. Be nice, and check out our Code of Conduct.










            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209324%2fplatform-agnostic-windowing-library%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            1
            down vote













            I wouldn't use #define macros. They expose the internal naming convention of your OS dependent functions to the world. Once you send out your library to others [as a shared library], you can never change your internal OS dependent names. The important thing is that public facing names be functions.



            For example, if two systems used gcc and created ELF binaries that only called your library functions, could you compile on (e.g.) FreeBSD and that binary would run without rebuild on linux. There are other issues with doing this, so it [probably] isn't practical, but, it's something to think about.



            A better way [what I've done when faced with a similar problem] is to put the OS dependent code in a .c and add static to the definitions.



            The public functions just call the static ones. The static function names are the same, regardless of platform



            The optimizer will either inline the static OS dependent function or will use tail call optimization. So, it's just as fast as macros but a lot cleaner.



            Side note: Your naming convention is a bit [MS] Windows centric (i.e. camel hump case). I prefer snake case (e.g. see GTK, etc.). For an example, see the bottom.





            vkwh.h:



            #pragma once

            #ifdef __cplusplus
            extern "C" {
            #endif

            VKWFWindow* VKWFCreateWindow(const char* title, int width, int height);
            VKWFBool VKWFWindowShouldClose(VKWFWindow* window);
            void VKWFWindowUpdate(VKWFWindow* window);
            void VKWFDestroyWindow(VKWFWindow* window);

            #ifdef __cplusplus
            }
            #endif




            vkwf.c:



            #include "vkwf.h"

            #ifdef VKWF_PLATFORM_WINDOWS
            #include "win32_window.c"
            #elif VKWF_PLATFORM_MACOS
            #include "macos_window.c"
            #elif VKWF_PLATFORM_LINUX
            #include "linux_window.c"
            #endif

            VKWFWindow* VKWFCreateWindow(const char* title, int width, int height)
            {
            return VKWFPlatformCreateWindow(title, width, height);
            }

            VKWFBool VKWFWindowShouldClose(VKWFWindow* window)
            {
            return VKWFPlatformWindowShouldClose(window);
            }

            void VKWFWindowUpdate(VKWFWindow* window)
            {
            VKWFPlatformUpdate(window);
            }

            void VKWFDestroyWindow(VKWFWindow* window)
            {
            VKWFPlatformDestroyWindow(window);
            }




            win32_window.c:



            #include "vkwf.h"

            static VKWFWindow*
            VKWFPlatformCreateWindow(const char* title, int width, int height)
            {
            // ...
            }

            static VKWFBool
            VKWFPlatformWindowShouldClose(VKWFWindow* window)
            {
            // ...
            }

            static void
            VKWFPlatformWindowUpdate(VKWFWindow* window)
            {
            // ...
            }

            static void
            VKWFPlatformDestroyWindow(VKWFWindow* window)
            {
            // ...
            }




            Here's an example of the snake case for the public functions. Note that since the platform specific functions are static, then can use shorter prefixes:



            #include "vkwf.h"

            #ifdef VKWF_PLATFORM_WINDOWS
            #include "win32_window.c"
            #elif VKWF_PLATFORM_MACOS
            #include "macos_window.c"
            #elif VKWF_PLATFORM_LINUX
            #include "linux_window.c"
            #endif

            VKWFWindow* VKWF_create_window(const char* title, int width, int height)
            {
            return platform_create_window(title, width, height);
            }

            VKWFBool VKWF_window_should_close(VKWFWindow* window)
            {
            return platform_window_should_close(window);
            }

            void VKWF_window_update(VKWFWindow* window)
            {
            platform_update(window);
            }

            void VKWF_destroy_window(VKWFWindow* window)
            {
            platform_destroy_window(window);
            }





            share|improve this answer



























              up vote
              1
              down vote













              I wouldn't use #define macros. They expose the internal naming convention of your OS dependent functions to the world. Once you send out your library to others [as a shared library], you can never change your internal OS dependent names. The important thing is that public facing names be functions.



              For example, if two systems used gcc and created ELF binaries that only called your library functions, could you compile on (e.g.) FreeBSD and that binary would run without rebuild on linux. There are other issues with doing this, so it [probably] isn't practical, but, it's something to think about.



              A better way [what I've done when faced with a similar problem] is to put the OS dependent code in a .c and add static to the definitions.



              The public functions just call the static ones. The static function names are the same, regardless of platform



              The optimizer will either inline the static OS dependent function or will use tail call optimization. So, it's just as fast as macros but a lot cleaner.



              Side note: Your naming convention is a bit [MS] Windows centric (i.e. camel hump case). I prefer snake case (e.g. see GTK, etc.). For an example, see the bottom.





              vkwh.h:



              #pragma once

              #ifdef __cplusplus
              extern "C" {
              #endif

              VKWFWindow* VKWFCreateWindow(const char* title, int width, int height);
              VKWFBool VKWFWindowShouldClose(VKWFWindow* window);
              void VKWFWindowUpdate(VKWFWindow* window);
              void VKWFDestroyWindow(VKWFWindow* window);

              #ifdef __cplusplus
              }
              #endif




              vkwf.c:



              #include "vkwf.h"

              #ifdef VKWF_PLATFORM_WINDOWS
              #include "win32_window.c"
              #elif VKWF_PLATFORM_MACOS
              #include "macos_window.c"
              #elif VKWF_PLATFORM_LINUX
              #include "linux_window.c"
              #endif

              VKWFWindow* VKWFCreateWindow(const char* title, int width, int height)
              {
              return VKWFPlatformCreateWindow(title, width, height);
              }

              VKWFBool VKWFWindowShouldClose(VKWFWindow* window)
              {
              return VKWFPlatformWindowShouldClose(window);
              }

              void VKWFWindowUpdate(VKWFWindow* window)
              {
              VKWFPlatformUpdate(window);
              }

              void VKWFDestroyWindow(VKWFWindow* window)
              {
              VKWFPlatformDestroyWindow(window);
              }




              win32_window.c:



              #include "vkwf.h"

              static VKWFWindow*
              VKWFPlatformCreateWindow(const char* title, int width, int height)
              {
              // ...
              }

              static VKWFBool
              VKWFPlatformWindowShouldClose(VKWFWindow* window)
              {
              // ...
              }

              static void
              VKWFPlatformWindowUpdate(VKWFWindow* window)
              {
              // ...
              }

              static void
              VKWFPlatformDestroyWindow(VKWFWindow* window)
              {
              // ...
              }




              Here's an example of the snake case for the public functions. Note that since the platform specific functions are static, then can use shorter prefixes:



              #include "vkwf.h"

              #ifdef VKWF_PLATFORM_WINDOWS
              #include "win32_window.c"
              #elif VKWF_PLATFORM_MACOS
              #include "macos_window.c"
              #elif VKWF_PLATFORM_LINUX
              #include "linux_window.c"
              #endif

              VKWFWindow* VKWF_create_window(const char* title, int width, int height)
              {
              return platform_create_window(title, width, height);
              }

              VKWFBool VKWF_window_should_close(VKWFWindow* window)
              {
              return platform_window_should_close(window);
              }

              void VKWF_window_update(VKWFWindow* window)
              {
              platform_update(window);
              }

              void VKWF_destroy_window(VKWFWindow* window)
              {
              platform_destroy_window(window);
              }





              share|improve this answer

























                up vote
                1
                down vote










                up vote
                1
                down vote









                I wouldn't use #define macros. They expose the internal naming convention of your OS dependent functions to the world. Once you send out your library to others [as a shared library], you can never change your internal OS dependent names. The important thing is that public facing names be functions.



                For example, if two systems used gcc and created ELF binaries that only called your library functions, could you compile on (e.g.) FreeBSD and that binary would run without rebuild on linux. There are other issues with doing this, so it [probably] isn't practical, but, it's something to think about.



                A better way [what I've done when faced with a similar problem] is to put the OS dependent code in a .c and add static to the definitions.



                The public functions just call the static ones. The static function names are the same, regardless of platform



                The optimizer will either inline the static OS dependent function or will use tail call optimization. So, it's just as fast as macros but a lot cleaner.



                Side note: Your naming convention is a bit [MS] Windows centric (i.e. camel hump case). I prefer snake case (e.g. see GTK, etc.). For an example, see the bottom.





                vkwh.h:



                #pragma once

                #ifdef __cplusplus
                extern "C" {
                #endif

                VKWFWindow* VKWFCreateWindow(const char* title, int width, int height);
                VKWFBool VKWFWindowShouldClose(VKWFWindow* window);
                void VKWFWindowUpdate(VKWFWindow* window);
                void VKWFDestroyWindow(VKWFWindow* window);

                #ifdef __cplusplus
                }
                #endif




                vkwf.c:



                #include "vkwf.h"

                #ifdef VKWF_PLATFORM_WINDOWS
                #include "win32_window.c"
                #elif VKWF_PLATFORM_MACOS
                #include "macos_window.c"
                #elif VKWF_PLATFORM_LINUX
                #include "linux_window.c"
                #endif

                VKWFWindow* VKWFCreateWindow(const char* title, int width, int height)
                {
                return VKWFPlatformCreateWindow(title, width, height);
                }

                VKWFBool VKWFWindowShouldClose(VKWFWindow* window)
                {
                return VKWFPlatformWindowShouldClose(window);
                }

                void VKWFWindowUpdate(VKWFWindow* window)
                {
                VKWFPlatformUpdate(window);
                }

                void VKWFDestroyWindow(VKWFWindow* window)
                {
                VKWFPlatformDestroyWindow(window);
                }




                win32_window.c:



                #include "vkwf.h"

                static VKWFWindow*
                VKWFPlatformCreateWindow(const char* title, int width, int height)
                {
                // ...
                }

                static VKWFBool
                VKWFPlatformWindowShouldClose(VKWFWindow* window)
                {
                // ...
                }

                static void
                VKWFPlatformWindowUpdate(VKWFWindow* window)
                {
                // ...
                }

                static void
                VKWFPlatformDestroyWindow(VKWFWindow* window)
                {
                // ...
                }




                Here's an example of the snake case for the public functions. Note that since the platform specific functions are static, then can use shorter prefixes:



                #include "vkwf.h"

                #ifdef VKWF_PLATFORM_WINDOWS
                #include "win32_window.c"
                #elif VKWF_PLATFORM_MACOS
                #include "macos_window.c"
                #elif VKWF_PLATFORM_LINUX
                #include "linux_window.c"
                #endif

                VKWFWindow* VKWF_create_window(const char* title, int width, int height)
                {
                return platform_create_window(title, width, height);
                }

                VKWFBool VKWF_window_should_close(VKWFWindow* window)
                {
                return platform_window_should_close(window);
                }

                void VKWF_window_update(VKWFWindow* window)
                {
                platform_update(window);
                }

                void VKWF_destroy_window(VKWFWindow* window)
                {
                platform_destroy_window(window);
                }





                share|improve this answer














                I wouldn't use #define macros. They expose the internal naming convention of your OS dependent functions to the world. Once you send out your library to others [as a shared library], you can never change your internal OS dependent names. The important thing is that public facing names be functions.



                For example, if two systems used gcc and created ELF binaries that only called your library functions, could you compile on (e.g.) FreeBSD and that binary would run without rebuild on linux. There are other issues with doing this, so it [probably] isn't practical, but, it's something to think about.



                A better way [what I've done when faced with a similar problem] is to put the OS dependent code in a .c and add static to the definitions.



                The public functions just call the static ones. The static function names are the same, regardless of platform



                The optimizer will either inline the static OS dependent function or will use tail call optimization. So, it's just as fast as macros but a lot cleaner.



                Side note: Your naming convention is a bit [MS] Windows centric (i.e. camel hump case). I prefer snake case (e.g. see GTK, etc.). For an example, see the bottom.





                vkwh.h:



                #pragma once

                #ifdef __cplusplus
                extern "C" {
                #endif

                VKWFWindow* VKWFCreateWindow(const char* title, int width, int height);
                VKWFBool VKWFWindowShouldClose(VKWFWindow* window);
                void VKWFWindowUpdate(VKWFWindow* window);
                void VKWFDestroyWindow(VKWFWindow* window);

                #ifdef __cplusplus
                }
                #endif




                vkwf.c:



                #include "vkwf.h"

                #ifdef VKWF_PLATFORM_WINDOWS
                #include "win32_window.c"
                #elif VKWF_PLATFORM_MACOS
                #include "macos_window.c"
                #elif VKWF_PLATFORM_LINUX
                #include "linux_window.c"
                #endif

                VKWFWindow* VKWFCreateWindow(const char* title, int width, int height)
                {
                return VKWFPlatformCreateWindow(title, width, height);
                }

                VKWFBool VKWFWindowShouldClose(VKWFWindow* window)
                {
                return VKWFPlatformWindowShouldClose(window);
                }

                void VKWFWindowUpdate(VKWFWindow* window)
                {
                VKWFPlatformUpdate(window);
                }

                void VKWFDestroyWindow(VKWFWindow* window)
                {
                VKWFPlatformDestroyWindow(window);
                }




                win32_window.c:



                #include "vkwf.h"

                static VKWFWindow*
                VKWFPlatformCreateWindow(const char* title, int width, int height)
                {
                // ...
                }

                static VKWFBool
                VKWFPlatformWindowShouldClose(VKWFWindow* window)
                {
                // ...
                }

                static void
                VKWFPlatformWindowUpdate(VKWFWindow* window)
                {
                // ...
                }

                static void
                VKWFPlatformDestroyWindow(VKWFWindow* window)
                {
                // ...
                }




                Here's an example of the snake case for the public functions. Note that since the platform specific functions are static, then can use shorter prefixes:



                #include "vkwf.h"

                #ifdef VKWF_PLATFORM_WINDOWS
                #include "win32_window.c"
                #elif VKWF_PLATFORM_MACOS
                #include "macos_window.c"
                #elif VKWF_PLATFORM_LINUX
                #include "linux_window.c"
                #endif

                VKWFWindow* VKWF_create_window(const char* title, int width, int height)
                {
                return platform_create_window(title, width, height);
                }

                VKWFBool VKWF_window_should_close(VKWFWindow* window)
                {
                return platform_window_should_close(window);
                }

                void VKWF_window_update(VKWFWindow* window)
                {
                platform_update(window);
                }

                void VKWF_destroy_window(VKWFWindow* window)
                {
                platform_destroy_window(window);
                }






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited 1 hour ago

























                answered 1 hour ago









                Craig Estey

                28014




                28014






















                    Gabriele Vierti is a new contributor. Be nice, and check out our Code of Conduct.










                    draft saved

                    draft discarded


















                    Gabriele Vierti is a new contributor. Be nice, and check out our Code of Conduct.













                    Gabriele Vierti is a new contributor. Be nice, and check out our Code of Conduct.












                    Gabriele Vierti is a new contributor. Be nice, and check out our Code of Conduct.
















                    Thanks for contributing an answer to Code Review Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    Use MathJax to format equations. MathJax reference.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209324%2fplatform-agnostic-windowing-library%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Morgemoulin

                    Scott Moir

                    Souastre