Splice 1.0.0 — the first public release. A cross-platform C++20 function-hooking library with a type-safe, fluent API across ARM64 / x86_64 on Android, Linux, and Windows.
#include <splice/splice.h>
// Observe every frame — by name, resolved at install time (dlsym / IAT)
SPLICE_HOOK_LIB("libEGL.so", eglSwapBuffers)
.after([](EGLBoolean, EGLDisplay, EGLSurface) { ++frame_count; });
// Conditionally rewrite an argument, then call through
SPLICE_HOOK(set_viewport)
.when([](int w, int) { return w == 160; })
.onInvoke([](auto orig, int, int h) { return orig(640, h); });Why Splice
- Compiler-checked hooks — signatures are deduced with
decltype, so a wrong callback shape is a compile error, not a silentvoid*-cast crash. This is the headline advantage over C-style hooking libraries. - A fluent DSL that reads like English —
.before/.after/.when/.once/.times/.onInvoke, plusSPLICE_HOOK_MEMBERandScopedHookRAII auto-disable. - Honest about its limits — no fake "uninstall"; a tiered
disable()instead.
Highlights
- decltype-deduced, type-safe hook signatures — no
void*casts - Fluent modifiers + diagnostic sugar (
SPLICE_TRACE/SPLICE_COUNT/SPLICE_TIME) - Atomic install + tiered
disable()(GOT/IAT pointer swap; inline atomic restore) - Lock-free RCU hook registry; per-call-site concurrency policy override
- GOT/PLT on ELF, IAT on PE, inline instruction patching on ARM64 + x86_64
- Exception-neutral (
-fno-exceptionscompatible); zero-alloc C-macro logging substrate
Platforms & CI
All green on every push:
| Job | Status |
|---|---|
| Linux x64 (gcc) + tests | ✅ |
| Linux x64 + ASan/UBSan | ✅ |
| Linux ARM64 (native) + tests | ✅ |
| Windows x64 (MSVC) + tests | ✅ |
| Android ARM64 (NDK cross-compile, build-only) | ✅ |
Add it to your project
Source consumption (no prebuilt binaries — ABI safety):
include(FetchContent)
FetchContent_Declare(splice
GIT_REPOSITORY https://github.com/allenk/splice.git
GIT_TAG v1.0.0)
FetchContent_MakeAvailable(splice)
target_link_libraries(your_target PRIVATE splice::splice)add_subdirectory() and find_package(splice CONFIG) are also supported.
Honest about limits
- No true reversible uninstall with memory reclaim — architecturally impossible for in-process, non-privileged inline hooks.
disable()is tiered instead. - No stop-the-world thread coordination (would need ptrace/root).
Docs & examples
docs/splice-guide.md— capability guide (中文版:docs/splice-guide-zh.md)docs/splice-vs-hooking-libraries.md— comparison vs other hooking libraries + the modern-C++ advantageexamples/—hello_hook,malloc_tracker,member_function, plus runnable GPU and Vulkan enhancer demos
Licensed under MIT.