-
Hi, We (Mike and I) are trying to build a C99 single-header-only unit test library which we’d like to release publicly and use in all our projects, not just our RayLib ones. However, it requires Windows.h. As you’re already aware this is a big issue for RayLib as it has struct and function names that collide with windows definitions as neither the functions/struct in windows.h nor RayLib are protected by either namespaces, prefixes or suffixes. The workarounds currently proposed don’t suit our library as it ultimately demands we structure our library like an STB library where we provide an implementation define to be placed in a source file somewhere (which can cause user friction) or we split the library into a header and source file to sandbox away the OS functions. After considering these workarounds originally seen in #1217, we think that if RayLib were to find different function names for (currently) 7 functions (as shown in #1217) this issue could be resolved forever. We realise more than 7 items would have to change to keep the API uniform and there’d be a cost, long term, to ensuring as RayLib grows there’d be no more name collisions in future but we still feel it’s a small price to pay for the greater compatibility / flexibility of RayLib. Here are our proposed renames (they're just examples):
Why can’t we just split our library in two as proposed by the workarounds? The fundamental issue is that even though RayLib is acting as a layer between the OS and the developer it shouldn’t forcefully stop other third party software interacting with the OS and having to use such work-arounds. Replace us with any other software library, the current work arounds say we/anyone-else MUST be sandboxed off to keep us away from RayLib. As a unit testing framework which could be testing game systems built on top of RayLib this is impossible for us in particular without sandboxing our windows function calls and sacrificing the convenience of our library's usability. RayLib is a library that separates the user from the OS but this issue also prevents the user from interacting with the OS in any way RayLib doesn’t already accommodate without sandboxing, e.g. Networking (as brought up by someone on Discord). There are a lot of issues on the GitHub repo and Discord server talking about this where people are trying to include both of those headers in the same compilation unit, not just us. If you agree this would be a good fix for RayLib we’re happy to do the work and make a pull request where we update the API and documentation. We hope this doesn’t sound like we are coming in and demanding that RayLib bend to our whim and do what we say, we're just curious to see if you'd be open to this change? |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 3 replies
-
Hi, I'm Mike. The guy mentioned above. |
Beta Was this translation helpful? Give feedback.
-
Yeah, I've asked about this before as well, and Ray basically said no, it would break too many things. |
Beta Was this translation helpful? Give feedback.
-
I don't think this is the way to solve your problem. As you mentioned, these changes are breaking the API in ways that would require changes to every raylib program written, ever. Additionally, we can't just change names because some other library or even a system API is using the same. That way, we could end up changing names every version or so to make integration with other libraries easier. |
Beta Was this translation helpful? Give feedback.
-
Sorry @dangmoody, no plans to change that. |
Beta Was this translation helpful? Give feedback.
-
Just for completion on this discussion, here there are three options to avoid conflicts, I tested all them and they work.
#if defined(_WIN32)
// To avoid conflicting windows.h symbols with raylib, some flags are defined
// WARNING: Those flags avoid inclusion of some Win32 headers that could be required
// by user at some point and won't be included...
//-------------------------------------------------------------------------------------
// If defined, the following flags inhibit definition of the indicated items.
#define NOGDICAPMASKS // CC_*, LC_*, PC_*, CP_*, TC_*, RC_
#define NOVIRTUALKEYCODES // VK_*
#define NOWINMESSAGES // WM_*, EM_*, LB_*, CB_*
#define NOWINSTYLES // WS_*, CS_*, ES_*, LBS_*, SBS_*, CBS_*
#define NOSYSMETRICS // SM_*
#define NOMENUS // MF_*
#define NOICONS // IDI_*
#define NOKEYSTATES // MK_*
#define NOSYSCOMMANDS // SC_*
#define NORASTEROPS // Binary and Tertiary raster ops
#define NOSHOWWINDOW // SW_*
#define OEMRESOURCE // OEM Resource values
#define NOATOM // Atom Manager routines
#define NOCLIPBOARD // Clipboard routines
#define NOCOLOR // Screen colors
#define NOCTLMGR // Control and Dialog routines
#define NODRAWTEXT // DrawText() and DT_*
#define NOGDI // All GDI defines and routines
#define NOKERNEL // All KERNEL defines and routines
#define NOUSER // All USER defines and routines
//#define NONLS // All NLS defines and routines
#define NOMB // MB_* and MessageBox()
#define NOMEMMGR // GMEM_*, LMEM_*, GHND, LHND, associated routines
#define NOMETAFILE // typedef METAFILEPICT
#define NOMINMAX // Macros min(a,b) and max(a,b)
#define NOMSG // typedef MSG and associated routines
#define NOOPENFILE // OpenFile(), OemToAnsi, AnsiToOem, and OF_*
#define NOSCROLL // SB_* and scrolling routines
#define NOSERVICE // All Service Controller routines, SERVICE_ equates, etc.
#define NOSOUND // Sound driver routines
#define NOTEXTMETRIC // typedef TEXTMETRIC and associated routines
#define NOWH // SetWindowsHook and WH_*
#define NOWINOFFSETS // GWL_*, GCL_*, associated routines
#define NOCOMM // COMM driver routines
#define NOKANJI // Kanji support stuff.
#define NOHELP // Help engine interface.
#define NOPROFILER // Profiler interface.
#define NODEFERWINDOWPOS // DeferWindowPos routines
#define NOMCX // Modem Configuration Extensions
// Type required before windows.h inclusion
typedef struct tagMSG *LPMSG;
#include <windows.h>
// Type required by some unused function...
typedef struct tagBITMAPINFOHEADER {
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;
#include <objbase.h>
#include <mmreg.h>
#include <mmsystem.h>
// Some required types defined for MSVC/TinyC compiler
#if defined(_MSC_VER) || defined(__TINYC__)
#include "propidl.h"
#endif
#endif |
Beta Was this translation helpful? Give feedback.
Just for completion on this discussion, here there are three options to avoid conflicts, I tested all them and they work.
Define the required symbols from
windows.h
instead of including the full header.Compile the
windows.h
with functions using it on an independent module/code-unit (a separate .c file to generate a separate .o) and link with it.Try to avoid conflics with
windows.h
defines: