Skip to content

Biblioteca Office C / FFI — Início Rápido

A API C do office_oxide é uma ABI estável e fininha sobre o núcleo Rust. Todos os bindings de mais alto nível (Go, C#, Node.js nativo) chamam esses mesmos pontos de entrada. Se sua linguagem ainda não tem um wrapper pronto, dá para linkar a biblioteca C diretamente.

A superfície autoritativa vive em include/office_oxide_c/office_oxide.h; este guia segue a mesma API.

Instalação

Opção 1 — compilar do source Rust

git clone https://github.com/yfedoseev/office_oxide
cd office_oxide
cargo build --release --lib

A biblioteca compartilhada vai para target/release/:

OS Arquivo
Linux liboffice_oxide.so
macOS liboffice_oxide.dylib
Windows office_oxide.dll (+ .lib import library)

O header fica em include/office_oxide_c/office_oxide.h.

Opção 2 — instalar uma biblioteca prebuilt

install -Dm644 include/office_oxide_c/office_oxide.h /usr/local/include/office_oxide.h
install -Dm755 target/release/liboffice_oxide.so     /usr/local/lib/liboffice_oxide.so

Ler um documento

#include <stdio.h>
#include <stdlib.h>
#include "office_oxide.h"

int main(void) {
    int err = 0;
    char *text = office_extract_text("report.docx", &err);
    if (!text) {
        fprintf(stderr, "office_oxide failed: code=%d\n", err);
        return 1;
    }
    printf("%s\n", text);
    office_oxide_free_string(text);
    return 0;
}

Compilar e rodar:

cc quickstart.c -I/usr/local/include -L/usr/local/lib -loffice_oxide -o quickstart
LD_LIBRARY_PATH=/usr/local/lib ./quickstart

API principal

Info da biblioteca

const char *version = office_oxide_version();          // "0.1.0" — não dê free
const char *fmt     = office_oxide_detect_format("f"); // "docx"/... ou NULL

Document (somente leitura)

int err = 0;
OfficeDocumentHandle *doc = office_document_open("file.xlsx", &err);
if (!doc) { /* tratar err */ }

const char *fmt = office_document_format(doc);         // "xlsx" — não dê free

char *text = office_document_plain_text(doc, &err);
char *md   = office_document_to_markdown(doc, &err);
char *html = office_document_to_html(doc, &err);
char *ir   = office_document_to_ir_json(doc, &err);

if (office_document_save_as(doc, "file.docx", &err) != 0) { /* tratar err */ }

office_oxide_free_string(text);
office_oxide_free_string(md);
office_oxide_free_string(html);
office_oxide_free_string(ir);

office_document_free(doc);

Abrir a partir de um buffer em memória:

uint8_t *data = ...;
size_t   len  = ...;
OfficeDocumentHandle *doc =
    office_document_open_from_bytes(data, len, "docx", &err);

format precisa ser uma das seis strings: "docx" | "xlsx" | "pptx" | "doc" | "xls" | "ppt".

EditableDocument

A edição preserva todas as partes OPC inalteradas. Apenas DOCX, XLSX e PPTX.

int err = 0;
OfficeEditableHandle *ed = office_editable_open("template.docx", &err);
if (!ed) { /* tratar err */ }

int64_t n = office_editable_replace_text(ed, "{{name}}", "Alice", &err);
if (n < 0) { /* tratar err */ }
printf("%lld substituições\n", (long long)n);

if (office_editable_save(ed, "out.docx", &err) != 0) { /* tratar err */ }

office_editable_free(ed);

Definir células XLSX:

OfficeEditableHandle *wb = office_editable_open("budget.xlsx", &err);

office_editable_set_cell(wb, 0, "A1", OFFICE_CELL_STRING, "Total", 0.0,  &err);
office_editable_set_cell(wb, 0, "B1", OFFICE_CELL_NUMBER,  NULL,   42.5, &err);
office_editable_set_cell(wb, 0, "C1", OFFICE_CELL_BOOLEAN, NULL,   1.0,  &err);
office_editable_set_cell(wb, 0, "D1", OFFICE_CELL_EMPTY,   NULL,   0.0,  &err);

office_editable_save(wb, "budget.xlsx", &err);
office_editable_free(wb);

Para booleanos: value_num diferente de zero significa true.

Serializar para um buffer no heap:

size_t   out_len = 0;
uint8_t *buf     = office_editable_save_to_bytes(ed, &out_len, &err);
if (!buf) { /* tratar err */ }
/* faz upload ou stream de buf[0..out_len] */
office_oxide_free_bytes(buf, out_len);

Helpers de uma chamada

char *text = office_extract_text("file.docx", &err);
char *md   = office_to_markdown("file.pptx", &err);
char *html = office_to_html("file.xlsx", &err);
/* libere cada um com office_oxide_free_string */

Regras de memória

  • char* devolvidos por office_document_*, office_editable_* e pelos helpers de uma chamada devem ser liberados com office_oxide_free_string(ptr).
  • uint8_t* devolvidos com out-parâmetro out_len devem ser liberados com office_oxide_free_bytes(ptr, len). O len precisa bater com o valor que a API escreveu em out_len.
  • Handles opacos liberam-se com o *_free() correspondente.
  • const char* retornados por office_oxide_version, office_oxide_detect_format, office_document_format são estáticos — não libere.

Erros

Toda chamada que pode falhar recebe um int *error_code como out-parameter:

int err = 0;
OfficeDocumentHandle *doc = office_document_open("missing.docx", &err);
if (!doc) {
    switch (err) {
        case OFFICE_ERR_IO:    fputs("erro de io\n", stderr); break;
        case OFFICE_ERR_PARSE: fputs("erro de parse\n", stderr); break;
        /* ... */
    }
}
Macro Valor Significado
OFFICE_OK 0 sucesso
OFFICE_ERR_INVALID_ARG 1 ponteiro nil / string de formato desconhecida
OFFICE_ERR_IO 2 erro de filesystem
OFFICE_ERR_PARSE 3 documento corrompido
OFFICE_ERR_EXTRACTION 4 parsing OK, mas o render falhou
OFFICE_ERR_INTERNAL 5 bug — abra uma issue
OFFICE_ERR_UNSUPPORTED 6 extensão/feature não suportada

Constantes de valor de célula

Macro Valor
OFFICE_CELL_EMPTY 0
OFFICE_CELL_STRING 1
OFFICE_CELL_NUMBER 2
OFFICE_CELL_BOOLEAN 3

Formatos legados

Abra com office_document_open — o formato é detectado pela extensão e verificado por magic bytes. office_document_save_as faz a conversão legado → OOXML de forma transparente:

OfficeDocumentHandle *doc = office_document_open("old.xls", &err);
office_document_save_as(doc, "modern.xlsx", &err);
office_document_free(doc);

Thread safety

Cada handle é do chamador — não compartilhe um único handle entre threads. Handles diferentes podem ser usados em paralelo; a biblioteca é reentrante.

C++

O header é envolvido por guardas extern "C", então entra direto numa unidade de tradução C++:

#include "office_oxide.h"

Combine com wrappers RAII (std::unique_ptr<OfficeDocumentHandle, decltype(&office_document_free)>) para limpeza exception-safe.

Solução de problemas

Sintoma Solução
Linker: undefined reference to office_document_open Adicione -loffice_oxide e o -L correspondente; confirme que a lib foi compilada com --release --lib.
Em runtime: error while loading shared libraries: liboffice_oxide.so Adicione o diretório da lib em LD_LIBRARY_PATH (Linux), DYLD_LIBRARY_PATH (macOS), ou copie ao lado do exe (Windows).
OFFICE_ERR_INVALID_ARG em open_from_bytes format precisa ser exatamente `“docx”
Double-free ou corrupção de heap Cada char* liberado com office_oxide_free_string, cada buffer de bytes com office_oxide_free_bytes(ptr, len) usando o out_len original.
office_editable_replace_text retorna 0 em XLSX Esperado — para edição de planilha use office_editable_set_cell.

Veja também