| Crates.io | alec-ffi |
| lib.rs | alec-ffi |
| version | 1.0.0 |
| created_at | 2026-01-21 18:31:02.97411+00 |
| updated_at | 2026-01-21 18:31:02.97411+00 |
| description | C/C++ bindings for ALEC compression library |
| homepage | |
| repository | https://github.com/zeekmartin/alec-codec |
| max_upload_size | |
| id | 2059838 |
| size | 63,963 |
C/C++ bindings for the ALEC (Adaptive Lazy Evolving Compression) library.
This crate provides a C-compatible FFI layer for ALEC, enabling use from C/C++ firmware and embedded systems.
#include "alec.h"
int main() {
// Create encoder
AlecEncoder* enc = alec_encoder_new();
// Encode a sensor reading
uint8_t output[256];
size_t output_len;
AlecResult res = alec_encode_value(
enc,
22.5, // value
0, // timestamp
"sensor_1", // source_id
output,
sizeof(output),
&output_len
);
if (res == ALEC_OK) {
printf("Compressed to %zu bytes\n", output_len);
}
// Cleanup
alec_encoder_free(enc);
return 0;
}
cd alec-ffi
cargo build --release
This produces:
target/release/libalec.a - Static librarytarget/release/libalec.so (Linux) / libalec.dylib (macOS) - Shared libraryWith static linking:
gcc -o myapp myapp.c \
-I alec-ffi/include \
target/release/libalec.a \
-lpthread -ldl -lm
With dynamic linking:
gcc -o myapp myapp.c \
-I alec-ffi/include \
-L target/release \
-lalec \
-lpthread -ldl -lm
# Set library path before running
export LD_LIBRARY_PATH=target/release:$LD_LIBRARY_PATH
./myapp
| Type | Description |
|---|---|
AlecEncoder* |
Opaque encoder handle |
AlecDecoder* |
Opaque decoder handle |
AlecResult |
Result code enum |
| Code | Value | Description |
|---|---|---|
ALEC_OK |
0 | Success |
ALEC_ERROR_INVALID_INPUT |
1 | Invalid input data |
ALEC_ERROR_BUFFER_TOO_SMALL |
2 | Output buffer too small |
ALEC_ERROR_ENCODING_FAILED |
3 | Encoding failed |
ALEC_ERROR_DECODING_FAILED |
4 | Decoding failed |
ALEC_ERROR_NULL_POINTER |
5 | NULL pointer provided |
ALEC_ERROR_INVALID_UTF8 |
6 | Invalid UTF-8 string |
ALEC_ERROR_FILE_IO |
7 | File I/O error |
ALEC_ERROR_VERSION_MISMATCH |
8 | Context version mismatch |
// Create/destroy
AlecEncoder* alec_encoder_new(void);
AlecEncoder* alec_encoder_new_with_checksum(void);
void alec_encoder_free(AlecEncoder* encoder);
// Encoding
AlecResult alec_encode_value(
AlecEncoder* encoder,
double value,
uint64_t timestamp,
const char* source_id,
uint8_t* output,
size_t output_capacity,
size_t* output_len
);
AlecResult alec_encode_multi(
AlecEncoder* encoder,
const double* values,
size_t value_count,
uint64_t timestamp,
const char* source_id,
uint8_t* output,
size_t output_capacity,
size_t* output_len
);
// Context management
AlecResult alec_encoder_save_context(AlecEncoder* encoder, const char* path, const char* sensor_type);
AlecResult alec_encoder_load_context(AlecEncoder* encoder, const char* path);
uint32_t alec_encoder_context_version(const AlecEncoder* encoder);
// Create/destroy
AlecDecoder* alec_decoder_new(void);
AlecDecoder* alec_decoder_new_with_checksum(void);
void alec_decoder_free(AlecDecoder* decoder);
// Decoding
AlecResult alec_decode_value(
AlecDecoder* decoder,
const uint8_t* input,
size_t input_len,
double* value,
uint64_t* timestamp
);
AlecResult alec_decode_multi(
AlecDecoder* decoder,
const uint8_t* input,
size_t input_len,
double* values,
size_t values_capacity,
size_t* values_count
);
// Context management
AlecResult alec_decoder_load_context(AlecDecoder* decoder, const char* path);
uint32_t alec_decoder_context_version(const AlecDecoder* decoder);
const char* alec_version(void);
const char* alec_result_to_string(AlecResult result);
Preloads allow instant optimal compression by loading pre-trained contexts:
// Encoder side
AlecEncoder* enc = alec_encoder_new();
alec_encoder_load_context(enc, "temperature_preload.alec-context");
// Decoder side (must use same preload!)
AlecDecoder* dec = alec_decoder_new();
alec_decoder_load_context(dec, "temperature_preload.alec-context");
rustup target add thumbv7em-none-eabihf
cargo build --release --target thumbv7em-none-eabihf
rustup target add thumbv6m-none-eabi
cargo build --release --target thumbv6m-none-eabi
Note: Cross-compilation for no_std targets requires additional configuration in the core ALEC library.
*_new() functions allocate memory*_free() functions deallocate memory*_free() functionNULL to *_free() functions is safe (no-op)AGPL-3.0 or Commercial License. See LICENSE file for details.