C / C++ (C ABI)
crates/ferro_ta_ffi is a stable C ABI over ferro_ta_core. It is the
foundation for the Go module and for future C-ABI bindings (C#, JVM, Ruby,
…), and it is usable directly from C and C++.
Getting the library
Each GitHub Release has one archive per platform,
ferro_ta-<version>-<platform>.tar.gz, containing include/ferro_ta.h,
the static library and the shared library (.so / .dylib; on Windows an
MSVC .dll with its import .lib).
To build from source:
cargo build -p ferro_ta_ffi --release
# header: crates/ferro_ta_ffi/include/ferro_ta.h
# library: target/release/libferro_ta_ffi.{a,so,dylib}
Example
#include <stdio.h>
#include "ferro_ta.h"
int main(void) {
const double close[] = {1, 2, 3, 4, 5};
double out[5];
int32_t status = ft_sma(close, 5, 3, out);
if (status != FT_OK) {
fprintf(stderr, "ft_sma: %s\n", ft_status_message(status));
return 1;
}
printf("%f\n", out[4]); /* 4.0 */
return 0;
}
cc -std=c99 -Iinclude example.c lib/libferro_ta_ffi.a -lm # add -lpthread -ldl on Linux
ABI conventions
Every function returns
int32_t:FT_OK(0) or anFT_ERR_*code;ft_status_messagedescribes it.Array inputs are
const double *sharing onesize_t len; outputs are caller-allocated arrays oflenelements, written only on success. An output may alias an input. Any array may beNULLwhenlen == 0.Periods are
int64_tin[minimum, 2^24](negative values are rejected, not wrapped; the cap keeps absurd values from exhausting memory), MA typesint32_tin 0–8, enumsint32_t(FT_OPTION_CALL, …), other scalarsdouble(must be finite).Scalar functions write each result through an output pointer (
ft_black_scholes_greeks→out_delta,out_gamma, …).Streaming indicators are opaque handles:
ft_stream_<x>_new/_update/_reset/_free. A handle is not thread-safe; free it exactly once (free(NULL)is a no-op).Kernel functions (
ft_sweep_*,ft_pbo_cscv, …) take arrays of different, row-major multi-dimensional shapes with explicitsize_tdimensions; the header lists each array’s element count underShapes:. Sizes such asn_combinationsmust equal a companion helper’s result (ft_pbo_n_combinations). Metric matrices haven_metric_colscolumns, which must equalft_sweep_n_metrics(), and are indexed byFT_METRIC_*.ft_backtest_ohlcvtakes its configuration as a settings vector indexed byFT_BT_*: declaredouble s[FT_BT_<LAST> + 1], fill it withft_backtest_default_settings(sizeof s / sizeof s[0], s)and overwrite entries. Always pass your array’s own length, neverft_backtest_n_settings(), so a newer library can’t write past it. A shorter vector, from an older header, gets defaults for the missing tail; a longer one is rejected. Kernel inputs documented as optional (volume,limit_prices) may beNULL.Results whose count depends on the data (
ft_extract_trades) are written into columns of a fixed capacity (n_bars) plus anout_n_tradescount; rows past the count hold -1 (indices) or NaN.A panic inside the core is caught and returned as
FT_ERR_PANIC; it never unwinds into the caller.
Every exported function is described in
crates/ferro_ta_ffi/ffi_spec.json (inputs, parameter kinds and minimums,
outputs), which is what language wrappers are generated from.