carb/detail/DeferredLoad.h

File members: carb/detail/DeferredLoad.h

// Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//

#include "../Defines.h"

#if !defined(CARB_REQUIRE_LINKED) || defined(DOXYGEN_BUILD)
#    define CARB_REQUIRE_LINKED 0
#endif

#define CARB_DETAIL_DEFINE_DEFERRED_LOAD(fn_name_, symbol_, type_pack_)                                                \
    inline auto fn_name_()->CARB_DEPAREN(type_pack_)                                                                   \
    {                                                                                                                  \
        CARB_DETAIL_DEFINE_DEFERRED_LOAD_IMPL(symbol_, type_pack_);                                                    \
    }                                                                                                                  \
    static_assert(true, "follow with ;")

#if CARB_REQUIRE_LINKED || defined DOXYGEN_BUILD

#    define CARB_DETAIL_DEFINE_DEFERRED_LOAD_IMPL(symbol_, type_pack_) return &symbol_

#elif CARB_PLATFORM_LINUX || CARB_PLATFORM_MACOS

#    define CARB_DETAIL_DEFINE_DEFERRED_LOAD_IMPL(symbol_, type_pack_)                                                 \
        auto impl = &symbol_;                                                                                          \
        CARB_FATAL_UNLESS(impl != nullptr, "Could not find `" CARB_STRINGIFY(                                          \
                                               symbol_) "` function -- make sure that libcarb.so is loaded");          \
        return impl

#elif CARB_PLATFORM_WINDOWS

#    include "../CarbWindows.h"

#    define CARB_DETAIL_DEFINE_DEFERRED_LOAD_IMPL(symbol_, type_pack_)                                                   \
        using TargetSymbolType = CARB_DEPAREN(type_pack_);                                                               \
        static TargetSymbolType cached_impl = nullptr;                                                                   \
        if (!cached_impl)                                                                                                \
        {                                                                                                                \
            HMODULE carb_dll_h = GetModuleHandleW(L"carb.dll");                                                          \
            CARB_FATAL_UNLESS(carb_dll_h != nullptr, "Could not find `carb.dll` module -- make sure that it is loaded"); \
            cached_impl = reinterpret_cast<TargetSymbolType>(GetProcAddress(carb_dll_h, CARB_STRINGIFY(symbol_)));       \
            CARB_FATAL_UNLESS(                                                                                           \
                cached_impl != nullptr,                                                                                  \
                "Could not find `" CARB_STRINGIFY(                                                                       \
                    symbol_) "` function at runtime -- #define CARB_REQUIRE_LINKED 1 before including this file");       \
        }                                                                                                                \
        return cached_impl

#else

#    define CARB_DETAIL_DEFINE_DEFERRED_LOAD_IMPL(symbol_, type_pack_) CARB_UNSUPPORTED_PLATFORM()

#endif