ABI estable de callbacks de C de HotPDF

HotPDFABI.dll expone funciones planas cdecl con valores de estado de ancho fijo, opaque handles, longitudes de bytes explícitas y la estructura versionada de callbacks hpdf_io_v1 declarada en Lib/hotpdf_abi.h

Salidas de build

Ejecute build-HotPDF-ABI.cmd para compilar las DLL Win32 y Win64 junto con sus import libraries bajo Lib/ABI/<platform>/Release

El ABI público usa nombres de exportación estables en minúsculas, mientras que hpdf_abi_version y hpdf_abi_io_v1_size permiten a los llamadores verificar el contrato antes de crear un documento

Funciones core

uint32_t hpdf_abi_version(void);
uint32_t hpdf_abi_io_v1_size(void);
hpdf_status hpdf_document_create(hpdf_document *handle);
hpdf_status hpdf_document_destroy(hpdf_document handle);
hpdf_status hpdf_document_load_from_io(
    hpdf_document handle,
    const hpdf_io_v1 *io,
    const char *password,
    size_t password_length);
hpdf_status hpdf_document_page_count(
    hpdf_document handle,
    uint32_t *page_count);
hpdf_status hpdf_document_save_to_io(
    hpdf_document handle,
    const hpdf_io_v1 *io);

Estructura de I/O versionada

hpdf_io_v1 io = {0};
io.struct_size = sizeof(io);
io.abi_version = HPDF_ABI_VERSION_1;
io.user_data = state;
io.read_at = read_at;
io.get_size = get_size;
io.write = write;
io.is_cancelled = is_cancelled;
io.progress = progress;
io.diagnostic = diagnostic;

struct_size es de 48 bytes en Win32 y 72 bytes en Win64, flags debe ser cero para el ABI v1, y estructuras futuras más grandes se pueden distinguir sin adivinar el layout de los campos

Todos los callbacks y las funciones exportadas usan cdecl, cada puntero de texto tiene una longitud de bytes explícita, y ningún string, clase, interface, enum, excepción ni Boolean de Delphi cruza la frontera

Input de acceso aleatorio

read_at recibe un offset absoluto de 64 bits y escribe directamente en el buffer de destino del parser, mientras que get_size reporta una sola vez el tamaño inmutable de la fuente cuando esta se adjunta

Las lecturas parciales exitosas se aceptan y se completan mediante llamadas repetidas al callback, de modo que los range stores y los lectores de red acotados no necesitan asignar un buffer intermedio del archivo completo

El estado del callback y los bytes de la fuente deben permanecer válidos hasta que el document handle se destruya o se cargue otra fuente en el handle

Output en stream

write recibe chunks de output secuenciales directamente de SaveLoadedDocumentToStream; las escrituras parciales exitosas se reintentan hasta que el chunk completo se acepta

Una escritura exitosa de cero bytes se rechaza como error de I/O porque no puede hacer progreso hacia adelante

Para las operaciones JSON execute y de comparación de dos handles, un callback de escritura fallido no se vuelve a llamar para publicar un resultado de error a través del mismo par de writer y user-data, incluso cuando OutputIO y ResultIO comparten ese par; los bytes candidatos parciales ya recibidos por el llamador siguen siendo responsabilidad del llamador

Los valores de estado de escritura fuera del rango de estados no cero definido, y los conteos de bytes exitosos de cero o excesivos, se convierten en HPDF_STATUS_IO_ERROR; el layout del record V1 y el comportamiento de escritura parcial exitosa permanecen sin cambios

Estado y ciclo de vida

EstadoSignificado
HPDF_STATUS_OKLa operación se completó
HPDF_STATUS_INVALID_ARGUMENTFalta un puntero o callback requerido, o un rango de bytes es inválido
HPDF_STATUS_INVALID_HANDLEEl handle es nulo, desconocido o ya fue destruido
HPDF_STATUS_INCOMPATIBLE_ABIEl tamaño de la estructura, la versión o los flags no son soportados
HPDF_STATUS_CANCELLEDEl callback de cancelación solicitó la terminación
HPDF_STATUS_IO_ERRORUn callback de input u output falló o violó su contrato de conteo
HPDF_STATUS_PARSE_ERROREl input se leyó con éxito pero no se aceptó como PDF
HPDF_STATUS_INTERNAL_ERRORUn fallo interno se detectó antes de cruzar el ABI

Cada hpdf_document_create exitoso debe emparejarse con un hpdf_document_destroy exitoso; la destrucción repetida devuelve HPDF_STATUS_INVALID_HANDLE

Los opaque handles son tokens monotónicos locales al proceso en lugar de direcciones de objetos, así que la reutilización del allocator no puede revivir un handle obsoleto

Las excepciones nunca cruzan la frontera de C, y el callback opcional de diagnóstico recibe los bytes del mensaje correspondiente antes de que una operación devuelva un estado de error

Concurrencia

Distintos handles se pueden usar concurrentemente, pero los llamadores deben serializar las operaciones y la destrucción del mismo handle

Callbacks Pascal heredados

THPDFABICallbacks y los helpers Pascal HPDFDoc* siguen siendo compatibles a nivel de código fuente para aplicaciones Delphi y C++Builder, pero las integraciones nativas de C deberían usar hotpdf_abi.h y las exportaciones v1 en minúsculas