Skip to content

Minimal C setup for the Galanthus C ABI.

Prerequisites

To consume the ABI you need:

  • The public header <galanthus/c_api/gln_capi.h>.
  • The matching shared library and import library for your platform.
  • A C99-capable compiler or an FFI tool that can call cdecl C functions.

At startup, compare GLN_API_VERSION with gln_get_api_version(). The current ABI version is 9u.

Build and Link

# GCC or Clang on Linux
cc -I/opt/galanthus/include -L/opt/galanthus/lib \
   -Wl,-rpath,/opt/galanthus/lib \
   hello.c -lgalanthus -o hello

# MSVC on Windows
cl /I C:\galanthus\include hello.c /link /LIBPATH:C:\galanthus\lib galanthus.lib

On Windows, place the DLL next to the loading executable or make it visible on PATH.

Minimal Backend Open

The public ABI opens provider integrations as generic backend handles. The example below initializes the library, creates a file-backed state store, opens a FinTS backend handle, and releases resources in reverse order.

#include <galanthus/c_api/gln_capi.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
    gln_error_t error = {0};
    gln_default_error(&error);
    gln_status_t s = gln_init_runtime(NULL, &error);
    if (s != GLN_OK) {
        fprintf(stderr, "init: %s\n", error.message ? error.message : "");
        gln_release_error(&error);
        return 1;
    }

    gln_state_store_t* state_store = NULL;
    s = gln_create_file_state_store("profile.state", NULL, &state_store, &error);
    if (s != GLN_OK) {
        fprintf(stderr, "state store: %s\n", error.message ? error.message : "");
        gln_release_error(&error);
        gln_shutdown_runtime();
        return 1;
    }

    const char pin_text[] = "1234";
    gln_secret_t* pin = NULL;
    s = gln_create_secret((const uint8_t*)pin_text, strlen(pin_text), &pin);
    if (s != GLN_OK) {
        gln_destroy_state_store(state_store);
        gln_shutdown_runtime();
        return 1;
    }

    gln_fints_config_t config = {0};

    gln_default_fints_config(&config);
    config.endpoint   = "https://bank.example/fints";
    config.bank_code  = "12345678";
    config.user_id    = "myuser";
    config.product_id = "myproduct1234567890ABCDE";

    gln_backend_t* backend = NULL;
    s = gln_open_fints_backend(&config, state_store, NULL, pin, &backend, &error);
    if (s != GLN_OK) {
        fprintf(stderr, "backend open: %s\n", error.message ? error.message : "");
        gln_release_error(&error);
    }

    gln_close_backend(backend);
    gln_destroy_secret(pin);
    gln_destroy_state_store(state_store);
    gln_shutdown_runtime();
    return s == GLN_OK ? 0 : 1;
}

The first real operation should inspect a gln_backend_result_t envelope: check the outcome, select the typed view matching the result kind, and destroy the envelope after reading all borrowed data. See Backend results for the full pattern.

Next Steps