/// Register a C plugin implementing `{{ trait_name }}` via a vtable.
///
/// # Parameters
///
/// - `name`: null-terminated UTF-8 plugin name. Must not be null.
/// - `vtable`: vtable with function pointers implementing the trait.
/// - `user_data`: opaque pointer forwarded to every vtable function.
/// - `out_error`: receives a heap-allocated error string on failure.
///
/// # Safety
///
/// All function pointers in `vtable` must remain valid until the plugin is
/// unregistered. `user_data` must be safe to use from any thread that calls
/// into the plugin.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn {{ full_register_name }}(
    name: *const std::ffi::c_char,
    vtable: *const {{ vtable_name }},
    user_data: *const std::ffi::c_void,
    out_error: *mut *mut std::ffi::c_char,
) -> i32 {
    if name.is_null() {
        ffi_set_out_error(out_error, "name must not be null");
        return 1;
    }
    if vtable.is_null() {
        ffi_set_out_error(out_error, "vtable must not be null");
        return 1;
    }
    let vtable_ref = &*vtable;
    if vtable_ref.free_string.is_none() {
        ffi_set_out_error(out_error, "vtable.free_string must not be null");
        return 1;
    }
