| /** |
| * This file has no copyright assigned and is placed in the Public Domain. |
| * This file is part of the mingw-w64 runtime package. |
| * No warranty is given; refer to the file DISCLAIMER.PD within this package. |
| */ |
| |
| #include <_mingw_mac.h> |
| |
| /* |
| * Example usage of this include file: |
| * |
| * #define RETT int |
| * #define FUNC func1 |
| * #define ARGS int arg1, int arg2 |
| * #define CALL arg1, arg2 |
| * #include "msvcrt_or_emu_glue.h" |
| * |
| * This example defines function named "func1" with signature: |
| * int __cdecl func1(int arg1, int arg2) { ... } |
| * |
| * This function "func1" would either call emulation function named "emu_func1" |
| * which always has to be declarated (it should be defined as static in the |
| * same source file) or would call function named "func1" from "msvcrt.dll" |
| * library if exists. |
| */ |
| |
| #if !defined(RETT) || !defined(FUNC) || !defined(ARGS) || !defined(CALL) |
| #error "Missing definitions for msvcrt_or_emu_glue.h" |
| #endif |
| |
| #if defined(FORCEEMU) || !defined(__LIBMSVCRT_OS__) |
| |
| /* |
| * If not compiling for os-system version of msvcrt.dll or FORCEEMU was |
| * specified then always use emulated version. |
| */ |
| |
| #ifdef NORETURN |
| __MINGW_ATTRIB_NORETURN |
| #endif |
| RETT __attribute__((alias(__MINGW64_STRINGIFY(__MINGW64_PASTE(emu_,FUNC))))) __cdecl FUNC(ARGS); |
| #ifdef NORETURN |
| __MINGW_ATTRIB_NORETURN |
| #endif |
| RETT (__cdecl *__MINGW_IMP_SYMBOL(FUNC))(ARGS) = FUNC; |
| |
| #else |
| |
| /* |
| * If compiling for os-system version of msvcrt.dll and FORCEEMU was not |
| * specified then try to use function from msvcrt.dll and fallback to |
| * emulated version only if function does not exist in msvcrt.dll. |
| */ |
| |
| #include <windows.h> |
| #include <msvcrt.h> |
| |
| #ifdef NORETURN |
| __MINGW_ATTRIB_NORETURN |
| #endif |
| static RETT __cdecl __MINGW64_PASTE(init_,FUNC)(ARGS); |
| |
| #ifdef NORETURN |
| __MINGW_ATTRIB_NORETURN |
| #endif |
| RETT (__cdecl *volatile __MINGW_IMP_SYMBOL(FUNC))(ARGS) = __MINGW64_PASTE(init_,FUNC); |
| |
| #ifdef NORETURN |
| __MINGW_ATTRIB_NORETURN |
| #endif |
| static RETT __cdecl __MINGW64_PASTE(init_,FUNC)(ARGS) |
| { |
| HMODULE msvcrt = __mingw_get_msvcrt_handle(); |
| #ifdef NORETURN |
| __MINGW_ATTRIB_NORETURN |
| #endif |
| RETT (__cdecl *func)(ARGS) = NULL; |
| |
| if (msvcrt) |
| func = (typeof(func))(void (__cdecl *)(void))GetProcAddress(msvcrt, __MINGW64_STRINGIFY(FUNC)); |
| |
| if (!func) |
| func = __MINGW64_PASTE(emu_,FUNC); |
| |
| (void)InterlockedExchangePointer((PVOID volatile *)&__MINGW_IMP_SYMBOL(FUNC), func); |
| |
| #ifndef NORETURN |
| return |
| #endif |
| func(CALL); |
| } |
| |
| #ifdef NORETURN |
| __MINGW_ATTRIB_NORETURN |
| #endif |
| RETT __cdecl FUNC(ARGS) |
| { |
| #ifndef NORETURN |
| return |
| #endif |
| __MINGW_IMP_SYMBOL(FUNC)(CALL); |
| } |
| |
| #endif |
| |
| /* Now undefine the definitions, so the file can be included more times. */ |
| #undef FORCEEMU |
| #undef NORETURN |
| #undef RETT |
| #undef FUNC |
| #undef ARGS |
| #undef CALL |