Affix

 view release on metacpan or  search on metacpan

infix/include/infix/infix.h  view on Meta::CPAN

 *
 * @section intro_sec Introduction
 *
 * `infix` is a powerful, modern, and lightweight C library for creating Foreign
 * Function Interface (FFI) trampolines at runtime. It allows you to dynamically
 * call C functions or create C callbacks from any language or environment, using
 * a simple, human-readable string-based syntax to describe function signatures.
 *
 * @section features_sec Key Features
 *
 * - **Simple Signature Syntax:** Describe complex C types, structs, and function
 *   prototypes with an intuitive string format.
 * - **Forward & Reverse Calls:** Create "forward" trampolines to call C from your
 *   code, and "reverse" trampolines (callbacks) to allow C to call back into your code.
 * - **Named Type Registry:** Define, reuse, and link complex, recursive, and
 *   mutually-dependent structs by name.
 * - **Cross-Platform:** Supports major architectures (x86-64, AArch64) and operating
 *   systems (Linux, macOS, Windows).
 * - **Secure:** Designed with modern security principles like W^X (Write XOR Execute)
 *   and hardened against memory corruption.
 * - **Lightweight & Embeddable:** A small, dependency-free library ideal for
 *   embedding in language runtimes, plugins, and other applications.
 *
 * @section usage_sec Basic Usage
 *
 * ```c
 * #include <infix/infix.h>
 * #include <stdio.h>
 *
 * // The C function we want to call.
 * int add(int a, int b) { return a + b; }
 *
 * int main() {
 *     infix_forward_t* trampoline = NULL;
 *     const char* signature = "(int, int) -> int";
 *
 *     // Create a "bound" trampoline JIT-compiled for the `add` function.
 *     infix_forward_create(&trampoline, signature, (void*)add, NULL);
 *
 *     // Get the callable function pointer from the trampoline.
 *     infix_cif_func cif = infix_forward_get_code(trampoline);
 *
 *     // Prepare arguments as an array of pointers.
 *     int a = 10, b = 32;
 *     void* args[] = { &a, &b };
 *     int result;
 *
 *     // Call the function through the FFI interface.
 *     cif(&result, args);
 *
 *     printf("Result: %d\n", result); // Output: Result: 42
 *
 *     infix_forward_destroy(trampoline);
 *     return 0;
 * }
 * ```
 */
#pragma once
/**
 * @defgroup version_info Version Information
 * @brief Macros defining the semantic version of the infix library.
 * @details The versioning scheme follows Semantic Versioning 2.0.0 (SemVer).
 * @{
 */
#define INFIX_MAJOR 0 /**< The major version number. Changes with incompatible API updates. */
#define INFIX_MINOR 1 /**< The minor version number. Changes with new, backward-compatible features. */
#define INFIX_PATCH 6 /**< The patch version number. Changes with backward-compatible bug fixes. */

#if defined(__has_c_attribute)
#define _INFIX_HAS_C_ATTRIBUTE(x) __has_c_attribute(x)
#else
#define _INFIX_HAS_C_ATTRIBUTE(x) 0
#endif

/**
 * @def INFIX_API
 * @brief Symbol visibility macro
 *
 * @details infix relies on a unity build so we've been lax about symbol visibility. Functions like `_infix_set_error`
 * or `_infix_type_recalculate_layout` are shared between internal modules (files included by `infix.c`) and thus cannot
 * be static. However, this means that if infix.c is compiled into a shared library (`libinfix.so`), all of these
 * internal _infix_* functions are exported in the dynamic symbol table. This pollutes the ABI and allows users to link
 * against internal functions that might change.
 */
#if defined(_WIN32) || defined(__CYGWIN__)
#if defined(INFIX_BUILDING_DLL)
#define INFIX_API __declspec(dllexport)
#elif defined(INFIX_USING_DLL)
#define INFIX_API __declspec(dllimport)
#else
#define INFIX_API
#endif
#elif defined(__GNUC__) || defined(__clang__)
#define INFIX_API __attribute__((visibility("default")))
#else
#define INFIX_API
#endif

/**
 * @def INFIX_NODISCARD
 * @brief A compatibility macro for the C23 `[[nodiscard]]` attribute.
 *
 * @details This attribute is used to issue a compiler warning if the return value
 * of a function is ignored by the caller. This is extremely useful for catching
 * bugs where an error code or an important result is not checked.
 *
 * This macro expands to:
 * - `[[nodiscard]]` on compilers that support the C23 standard syntax.
 * - `__attribute__((warn_unused_result))` on GCC and Clang.
 * - `_Check_return_` on Microsoft Visual C++.
 * - Nothing on other compilers.
 *
 * This is aliased as `c23_nodiscard` in `compat_c23.h`.
 */
#if _INFIX_HAS_C_ATTRIBUTE(nodiscard) && !defined(__GNUC__) && !defined(__clang__)
#define INFIX_NODISCARD [[nodiscard]]
#elif defined(__GNUC__) || defined(__clang__)
#define INFIX_NODISCARD __attribute__((warn_unused_result))
#elif defined(_MSC_VER)
#define INFIX_NODISCARD _Check_return_
#else



( run in 1.119 second using v1.01-cache-2.11-cpan-99c4e6809bf )