Stabile C-Callback-ABI von HotPDF
HotPDFABI.dll stellt flache cdecl-Funktionen mit Statuswerten fester Breite, undurchsichtigen Handles, expliziten Byte-Längen und der versionierten Callback-Struktur hpdf_io_v1 aus Lib/hotpdf_abi.h bereit
Build-Ergebnisse
Führen Sie build-HotPDF-ABI.cmd aus, um Win32- und Win64-DLLs sowie Importbibliotheken unter Lib/ABI/<platform>/Release zu erstellen
Die öffentliche ABI verwendet stabile kleingeschriebene Exportnamen. hpdf_abi_version und hpdf_abi_io_v1_size erlauben es Aufrufern, den Vertrag vor Erstellung eines Dokuments zu prüfen
Kernfunktionen
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);
Versionierte I/O-Struktur
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 beträgt 48 Bytes auf Win32 und 72 Bytes auf Win64, flags muss für ABI v1 null sein, und größere künftige Strukturen lassen sich unterscheiden, ohne das Feldlayout zu raten
Alle Callbacks und exportierten Funktionen nutzen cdecl, jeder Textzeiger hat eine explizite Bytelänge, und kein Delphi-String, keine Klasse, kein Interface, kein Enum, keine Ausnahme und kein Boolean überquert die Grenze
Random-Access-Eingabe
read_at erhält einen absoluten 64-Bit-Offset und schreibt direkt in den Zielpuffer des Parsers, während get_size die unveränderliche Quellgröße einmal beim Anbinden der Quelle meldet
Die Callback-Tabelle ermöglicht Eingabe mit Direktzugriff, gestreamte Ausgabe, Abbruch, Fortschritt und strukturierte Diagnose, ohne dass die Bibliothek Speicher oder Handles des Aufrufers besitzt
Die Versionierung der Struktur und explizite Größenprüfungen erlauben Erweiterungen, ohne bestehende native Aufrufer zu brechen
Gestreamte Ausgabe
write empfängt sequenzielle Ausgabeblöcke direkt von SaveLoadedDocumentToStream; teilweise erfolgreiche Writes werden wiederholt, bis der komplette Block akzeptiert ist
Ein erfolgreicher Write mit null Bytes wird als E/A-Fehler zurückgewiesen, weil er keinen Fortschritt ermöglichen kann
Bei JSON-execute- und Zwei-Handle-Vergleichsoperationen wird ein fehlgeschlagener Write-Callback nicht erneut aufgerufen, um ein Fehlerergebnis über dasselbe Writer- und User-Data-Paar zu publizieren, auch wenn sich OutputIO und ResultIO dieses Paar teilen; teilweise bereits vom Aufrufer empfangene Kandidatenbytes bleiben in dessen Verantwortung
Write-Statuswerte außerhalb des definierten Nicht-null-Statusbereichs sowie null oder übermäßige erfolgreiche Bytezahlen werden zu HPDF_STATUS_IO_ERROR; das V1-Record-Layout und das erfolgreiche Partial-Write-Verhalten bleiben unverändert
Status und Lebenszyklus
| Status | Bedeutung |
|---|---|
HPDF_STATUS_OK | Die Operation wurde abgeschlossen |
HPDF_STATUS_INVALID_ARGUMENT | Ein erforderlicher Zeiger oder Callback fehlt, oder ein Bytebereich ist ungültig |
HPDF_STATUS_INVALID_HANDLE | Das Handle ist null, unbekannt oder bereits zerstört |
HPDF_STATUS_INCOMPATIBLE_ABI | Größe, Version oder Flags der Struktur werden nicht unterstützt |
HPDF_STATUS_CANCELLED | Der Abbruch-Callback hat einen Abbruch angefordert |
HPDF_STATUS_IO_ERROR | Ein Eingabe- oder Ausgabe-Callback ist fehlgeschlagen oder hat seine Anzahl-Konvention verletzt |
HPDF_STATUS_PARSE_ERROR | Die Eingabe wurde gelesen, aber nicht als PDF akzeptiert |
HPDF_STATUS_INTERNAL_ERROR | Ein interner Fehler wurde abgefangen, bevor er die ABI-Grenze überschritt |
Jedem erfolgreichen hpdf_document_create muss ein erfolgreicher hpdf_document_destroy gegenüberstehen; wiederholtes Zerstören liefert HPDF_STATUS_INVALID_HANDLE
Opake Handles sind monotone prozesslokale Token statt Objektadressen, sodass Allokator-Wiederverwendung kein veraltetes Handle wiederbeleben kann
Ausnahmen überqueren nie die C-Grenze, und der optionale Diagnose-Callback empfängt die zugehörigen Meldungsbytes, bevor eine Operation einen Fehlerstatus zurückliefert
Nebenläufigkeit
Verschiedene Handles dürfen gleichzeitig genutzt werden, aber Aufrufer müssen Operationen und Zerstörung desselben Handles serialisieren
Legacy-Pascal-Callbacks
THPDFABICallbacks und die HPDFDoc*-Pascal-Helfer bleiben für Delphi- und C++Builder-Anwendungen quellkompatibel; native-C-Integrationen sollten hotpdf_abi.h und die kleingeschriebenen v1-Exporte verwenden