ABI de devolución de llamada C estable de HotPDF

HotPDFABI.dll expone funciones cdecl planas con valores de estado de ancho fijo, identificadores opacos, longitudes de byte explícitas y la estructura de devolución de llamada versionada hpdf_io_v1 declarada en Lib/hotpdf_abi.h

Salidas de compilación

Ejecute build-HotPDF-ABI.cmd para compilar DLL de Win32 y Win64 además de bibliotecas de importación en Lib/ABI/<platform>/Release

La ABI pública 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 principales

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 E/S 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 de 72 bytes en Win64, flags debe ser cero para ABI v1, y las estructuras futuras más grandes se pueden distinguir sin adivinar la disposición de los campos

Todas las devoluciones de llamada y las funciones exportadas usan cdecl, cada puntero de texto tiene una longitud de byte explícita, y ninguna cadena, clase, interfaz, enumeración, excepción o Boolean de Delphi cruza el límite

Entrada de acceso aleatorio

read_at recibe un desplazamiento absoluto de 64 bits y escribe directamente en el búfer de destino del analizador, mientras que get_size informa una vez del tamaño inmutable del origen cuando el origen se adjunta

Las lecturas parciales correctas se aceptan y se completan mediante llamadas de devolución de llamada repetidas, por lo que los almacenes de rangos y los lectores de red acotados no necesitan asignar un búfer intermedio de archivo completo

El estado de la devolución de llamada y los bytes de origen deben permanecer válidos hasta que se destruya el identificador del documento o se cargue otro origen en el identificador

Salida en flujo

write recibe fragmentos de salida secuenciales directamente de SaveLoadedDocumentToStream; las escrituras parciales correctas se reintentan hasta que se acepta el fragmento completo

Una escritura correcta de cero bytes se rechaza como error de E/S porque no puede avanzar

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 escritor y datos de usuario, incluido 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 estado distinto de cero definido, y los recuentos de bytes correctos cero o excesivos, se convierten en HPDF_STATUS_IO_ERROR; el layout del record V1 y el comportamiento de escritura parcial correcta permanecen sin cambios

Estado y ciclo de vida

EstadoSignificado
HPDF_STATUS_OKLa operación se completó
HPDF_STATUS_INVALID_ARGUMENTFalta un puntero o una devolución de llamada obligatorios o un rango de bytes no es válido
HPDF_STATUS_INVALID_HANDLEEl identificador es nulo, desconocido o ya está destruido
HPDF_STATUS_INCOMPATIBLE_ABIEl tamaño de la estructura, la versión o los indicadores no son compatibles
HPDF_STATUS_CANCELLEDLa devolución de llamada de cancelación solicitó la terminación
HPDF_STATUS_IO_ERRORUna devolución de llamada de entrada o salida falló o violó su contrato de recuento
HPDF_STATUS_PARSE_ERRORLa entrada se leyó correctamente pero no se aceptó como PDF
HPDF_STATUS_INTERNAL_ERRORSe detectó un error interno antes de que cruzara la ABI

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

Los identificadores opacos son tokens monotónicos locales al proceso en lugar de direcciones de objeto, por lo que la reutilización del asignador no puede revivir un identificador obsoleto

Las excepciones nunca cruzan el límite de C, y la devolución de llamada de diagnóstico opcional recibe los bytes de mensaje correspondientes antes de que una operación devuelva un estado de error

Concurrencia

Se pueden usar identificadores distintos de forma concurrente, pero los llamadores deben serializar las operaciones y la destrucción del mismo identificador

Devoluciones de llamada Pascal heredadas

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