Skip to content

Instantly share code, notes, and snippets.

@Chubek
Created June 8, 2026 00:58
Show Gist options
  • Select an option

  • Save Chubek/4d9f885f1189ded7a8693cf18d1247a6 to your computer and use it in GitHub Desktop.

Select an option

Save Chubek/4d9f885f1189ded7a8693cf18d1247a6 to your computer and use it in GitHub Desktop.
Hedley API Boilerplate
/**
* @file myapihed_api.h
* @brief Portable API macros for the MYAPIHED library, built on top of hedley.h
*/
#ifndef MYAPIHED_API_H
#define MYAPIHED_API_H
#include "hedley.h"
/* =========================================================================
* VERSION
* ========================================================================= */
#define MYAPIHED_VERSION_MAJOR 1
#define MYAPIHED_VERSION_MINOR 0
#define MYAPIHED_VERSION_PATCH 0
/**
* Numeric version: encoded as (major * 10000) + (minor * 100) + patch
* e.g. 1.2.3 -> 10203
* 2.14.7 -> 21407
*/
#define MYAPIHED_VERSION_NUM \
((MYAPIHED_VERSION_MAJOR * 10000) + (MYAPIHED_VERSION_MINOR * 100) \
+ (MYAPIHED_VERSION_PATCH))
/** String version, e.g. "1.0.0" */
#define MYAPIHED_STRINGIFY_(x) #x
#define MYAPIHED_STRINGIFY(x) MYAPIHED_STRINGIFY_ (x)
#define MYAPIHED_VERSION_STR \
MYAPIHED_STRINGIFY (MYAPIHED_VERSION_MAJOR) \
"." MYAPIHED_STRINGIFY (MYAPIHED_VERSION_MINOR) "." MYAPIHED_STRINGIFY ( \
MYAPIHED_VERSION_PATCH)
/** Human-readable "about" string */
#define MYAPIHED_ABOUT \
"MYAPIHED Library v" MYAPIHED_VERSION_STR \
" -- Copyright (C) 2026 MYAPIHED Authors. All rights reserved."
/* =========================================================================
* SYMBOL VISIBILITY (hedley.h lines 1641-1676)
*
* Define MYAPIHED_BUILD when compiling the library itself.
* Consumers only include this header; they must NOT define MYAPIHED_BUILD.
* ========================================================================= */
/** Public API symbol – exported when building, imported when consuming. */
#if defined(MYAPIHED_BUILD)
#define MYAPIHED_API \
HEDLEY_PUBLIC /* __declspec(dllexport) / visibility("default") */
#else
#define MYAPIHED_API \
HEDLEY_IMPORT /* __declspec(dllimport) / extern */
#endif
/**
* Private symbol – hidden from the shared-library ABI.
* Use on internal helper functions that must never be called by consumers.
* (hedley.h: HEDLEY_PRIVATE -> visibility("hidden") on ELF, empty on MSVC)
*/
#define MYAPIHED_PRIVATE HEDLEY_PRIVATE
/**
* For functions that are provided only in a shared library and MUST be
* loaded at runtime via dlopen/LoadLibrary + dlsym/GetProcAddress.
* Marks the declaration as an import so that no static-link stub is emitted.
*/
#define MYAPIHED_DYNLIB HEDLEY_IMPORT
/* =========================================================================
* INLINING (hedley.h lines 1555-1638)
* ========================================================================= */
/** Force inlining: __attribute__((always_inline)) / __forceinline */
#define MYAPIHED_ALWAYS_INLINE HEDLEY_ALWAYS_INLINE
/** Prevent inlining: __attribute__((noinline)) / __declspec(noinline) */
#define MYAPIHED_NEVER_INLINE HEDLEY_NEVER_INLINE
/* =========================================================================
* FUNCTION ATTRIBUTES (hedley.h lines 1399-1497)
* ========================================================================= */
/**
* Pure function: return value depends only on arguments + global state;
* no observable side effects. Enables CSE and other optimisations.
* (hedley.h: __attribute__((pure)))
*/
#define MYAPIHED_PURE HEDLEY_PURE
/**
* Const function: return value depends ONLY on arguments (no globals read);
* strictly stronger than PURE.
* (hedley.h: __attribute__((const)) or alias to HEDLEY_PURE)
*/
#define MYAPIHED_CONST HEDLEY_CONST
/**
* Malloc-like: returned pointer does not alias any existing object.
* (hedley.h: __attribute__((malloc)) / __declspec(restrict))
*
* Usage:
* MYAPIHED_API MYAPIHED_MALLOC(size)
* void *myapihed_alloc(size_t size);
*
* The parameter name 'n' is kept as a documentation convention; it is
* not evaluated – only the annotation matters to the compiler.
*/
#define MYAPIHED_MALLOC(n) HEDLEY_MALLOC /* n = size (documentation only) */
/* =========================================================================
* BRANCH PREDICTION HINTS (hedley.h lines 1336-1393)
* ========================================================================= */
/** Hint that the expression is TRUE in the common case. */
#define MYAPIHED_LIKELY(expr) HEDLEY_LIKELY (expr)
/** Hint that the expression is FALSE in the common case. */
#define MYAPIHED_UNLIKELY(expr) HEDLEY_UNLIKELY (expr)
/* =========================================================================
* HOT / COLD (not in this hedley.h build; defined here in Hedley style)
* ========================================================================= */
#if !defined(MYAPIHED_HOT)
#if HEDLEY_HAS_ATTRIBUTE(hot) || HEDLEY_GCC_VERSION_CHECK(4, 3, 0)
#define MYAPIHED_HOT __attribute__ ((__hot__))
#else
#define MYAPIHED_HOT
#endif
#endif
#if !defined(MYAPIHED_COLD)
#if HEDLEY_HAS_ATTRIBUTE(cold) || HEDLEY_GCC_VERSION_CHECK(4, 3, 0)
#define MYAPIHED_COLD __attribute__ ((__cold__))
#else
#define MYAPIHED_COLD
#endif
#endif
/* =========================================================================
* PRINTF FORMAT CHECKING (hedley.h lines 1289-1318)
*
* Usage:
* MYAPIHED_API MYAPIHED_PRINTF(1, 2)
* void myapihed_log(const char *fmt, ...);
*
* fmt_idx – 1-based index of the format-string argument
* first_arg – 1-based index of the first variadic argument
* (use 0 for vprintf-style functions)
* ========================================================================= */
#define MYAPIHED_PRINTF(fmt_idx, first_arg) \
HEDLEY_PRINTF_FORMAT (fmt_idx, first_arg)
/* =========================================================================
* NO-RETURN (hedley.h lines 1145-1186)
*
* Mark functions that never return (abort, longjmp wrappers, etc.)
* Compiler uses this to suppress "missing return" warnings on callers.
* ========================================================================= */
#define MYAPIHED_NORETURN HEDLEY_NO_RETURN
/* =========================================================================
* PLUGIN METADATA MACROS
*
* These are purely declarative metadata tags embedded inside plugin
* translation units. They follow the same convention used by projects
* such as GStreamer, LADSPA, LV2, and Audacity:
*
* • Each macro expands to a static const char[] so the information
* survives in the object file and can be queried with `strings` or
* a dedicated loader.
* • MYAPIHED_PLUGIN_AUTHOR / MYAPIHED_PLUGIN_MAINTAINER may appear more
* than once in the same translation unit.
* • MYAPIHED_PLUGIN_CALL_ON_INIT / MYAPIHED_PLUGIN_CALL_ON_EXIT register
* constructor/destructor callbacks using __attribute__((constructor))
* on GCC/Clang or #pragma init_seg on MSVC.
* ========================================================================= */
/** Plugin canonical name, e.g. MYAPIHED_PLUGIN_NAME("my-effect") */
#define MYAPIHED_PLUGIN_NAME(n) \
static const char \
_myapihed_plugin_name[] HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ ( \
(unused)) \
= "" n ""
/** Plugin version string, e.g. MYAPIHED_PLUGIN_VERSION("1.2.3") */
#define MYAPIHED_PLUGIN_VERSION(v) \
static const char \
_myapihed_plugin_version[] HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ ( \
(unused)) \
= "" v ""
/** SPDX license identifier, e.g. MYAPIHED_PLUGIN_LICENSE("MIT") */
#define MYAPIHED_PLUGIN_LICENSE(l) \
static const char \
_myapihed_plugin_license[] HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ ( \
(unused)) \
= "" l ""
/** Short description, e.g. MYAPIHED_PLUGIN_DESC("Adds reverb to audio") */
#define MYAPIHED_PLUGIN_DESC(d) \
static const char \
_myapihed_plugin_desc[] HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ ( \
(unused)) \
= "" d ""
/** Homepage / repository URL, e.g.
* MYAPIHED_PLUGIN_HOMEPAGE("https://example.com") */
#define MYAPIHED_PLUGIN_HOMEPAGE(u) \
static const char \
_myapihed_plugin_homepage[] HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ ( \
(unused)) \
= "" u ""
/*
* For MAINTAINER and AUTHOR we use a __COUNTER__-based unique symbol so the
* macro can be repeated multiple times in the same translation unit without
* triggering duplicate-symbol errors.
*
* __COUNTER__ is supported by GCC >= 4.3, Clang, MSVC >= 2005, and ICC.
* On compilers without it we fall back to __LINE__ (still allows multiple
* authors as long as they are on different lines, which is the normal case).
*l/
#if defined(__COUNTER__)
#define MYAPIHED_PLUGIN_UNIQUE_ __COUNTER__
#else
#define MYAPIHED_PLUGIN_UNIQUE_ __LINE__
#endif
/* Internal paste helpers */
#define MYAPIHED_PASTE__(a, b) a##b
#define MYAPIHED_PASTE_(a, b) MYAPIHED_PASTE__ (a, b)
/**
* Maintainer record. May appear once or more.
* MYAPIHED_PLUGIN_MAINTAINER("Alice Smith", "alice@example.com")
*/
#define MYAPIHED_PLUGIN_MAINTAINER(n, e) \
static const char MYAPIHED_PASTE_ (_myapihed_plugin_maintainer_, \
MYAPIHED_PLUGIN_UNIQUE_) \
[] HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ ((unused)) \
= "maintainer:" n " <" e ">"
/**
* Author record. May appear multiple times.
* MYAPIHED_PLUGIN_AUTHOR("Bob Jones", "bob@example.com")
* MYAPIHED_PLUGIN_AUTHOR("Carol Wu", "carol@example.com")
*/
#define MYAPIHED_PLUGIN_AUTHOR(a, e) \
static const char MYAPIHED_PASTE_ (_myapihed_plugin_author_, \
MYAPIHED_PLUGIN_UNIQUE_) \
[] HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ ((unused)) \
= "author:" a " <" e ">"
/* -------------------------------------------------------------------------
* Constructor / destructor callbacks
* ------------------------------------------------------------------------- */
#if defined(_MSC_VER)
/*
* MSVC: use CRT init-seg hooks.
* The function is placed in the .CRT$XCU (constructor) or .CRT$XPU
* (pre-termination) segment and called automatically by the CRT.
*/
#pragma section(".CRT$XCU", read)
#pragma section(".CRT$XPU", read)
#define MYAPIHED_PLUGIN_CALL_ON_INIT(fn) \
static void fn (void); \
__declspec (allocate (".CRT$XCU")) static void ( \
*MYAPIHED_PASTE_ (_myapihed_init_ptr_, __COUNTER__)) (void) \
= (fn); \
static void fn (void)
#define MYAPIHED_PLUGIN_CALL_ON_EXIT(fn) \
static void fn (void); \
__declspec (allocate (".CRT$XPU")) static void ( \
*MYAPIHED_PASTE_ (_myapihed_exit_ptr_, __COUNTER__)) (void) \
= (fn); \
static void fn (void)
#elif defined(__GNUC__) || defined(__clang__)
/*
* GCC / Clang: __attribute__((constructor)) / __attribute__((destructor))
* Priority 101 leaves room below 100 for C++ static objects.
*/
#define MYAPIHED_PLUGIN_CALL_ON_INIT(fn) \
__attribute__ ((__constructor__ (101))) static void fn (void)
#define MYAPIHED_PLUGIN_CALL_ON_EXIT(fn) \
__attribute__ ((__destructor__ (101))) static void fn (void)
#else
/* Unknown toolchain: best-effort via _init / _fini weak symbols. */
#define MYAPIHED_PLUGIN_CALL_ON_INIT(fn) static void fn (void)
#define MYAPIHED_PLUGIN_CALL_ON_EXIT(fn) static void fn (void)
#warning "MYAPIHED: automatic plugin init/exit not supported on this compiler."
#endif
#if __cplusplus
#define MYAPIHED_XDECL(l) extern #l
#define MYAPIHED_XDECL_BEGIN(l) \
extern #l \
{
#define MYAPIHED_XDECL_END() }
#else
#define MYAPIHED_XDECL(l)
#define MYAPIHED_XDECL_BEGIN(l)
#define MYAPIHED_XDECL_END(l)
#endif
#endif /* MYAPIHED_API_H */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment