Stabilne ABI wywołań zwrotnych C w HotPDF
HotPDFABI.dll wystawia płaskie funkcje cdecl ze statusami o stałej szerokości, nieprzezroczystymi uchwytami, jawnymi długościami w bajtach oraz wersjonowaną strukturą wywołań zwrotnych hpdf_io_v1 zadeklarowaną w Lib/hotpdf_abi.h
Wyniki budowania
Uruchom build-HotPDF-ABI.cmd, aby zbudować DLL-e Win32 i Win64 plus biblioteki importu pod Lib/ABI/<platform>/Release
Publiczne ABI używa stabilnych małoliterowych nazw eksportów, a hpdf_abi_version i hpdf_abi_io_v1_size pozwalają wywołującym zweryfikować kontrakt przed utworzeniem dokumentu
Funkcje główne
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);
Wersjonowana struktura I/O
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 to 48 bajty na Win32 i 72 bajty na Win64, flags muszą być zerem dla ABI v1, a większe przyszłe struktury można rozróżnić bez zgadywania układu pól
Wszystkie wywołania zwrotne i eksportowane funkcje używają cdecl, każdy wskaźnik tekstu ma jawną długość w bajtach, a żadne ciągi, klasy, interfejsy, enumy, wyjątki ani Boolean z Delphi nie przekraczają granicy
Wejście o dostępie swobodnym
read_at otrzymuje bezwzględny offset 64-bit i pisze bezpośrednio do bufora docelowego parsera, a get_size raportuje niezmienny rozmiar źródła raz, gdy źródło jest podłączane
Częściowe udane odczyty są przyjmowane i uzupełniane przez powtarzane wywołania zwrotne, więc magazyny zakresowe i ograniczone czytniki sieciowe nie muszą alokować pośredniego bufora całego pliku
Stan wywołania zwrotnego i bajty źródła muszą pozostać ważne, dopóki uchwyt dokumentu nie zostanie zniszczony albo do uchwytu nie zostanie załadowane inne źródło
Wyjście strumieniowe
write otrzymuje sekwencyjne fragmenty wyjścia bezpośrednio z SaveLoadedDocumentToStream; częściowe udane zapisy są ponawiane, dopóki kompletny fragment nie zostanie przyjęty
Udany zapis o zerowej liczbie bajtów jest odrzucany jako błąd I/O, bo nie może zrobić postępu do przodu
Dla operacji execute JSON i porównania dwóch uchwytów nieudany callback zapisu nie jest wywoływany ponownie, by publikować wynik błędu przez tę samą parę writer i user-data, także gdy OutputIO i ResultIO współdzielą tę parę; częściowe bajty kandydata już dostarczone wywołującemu pozostają jego odpowiedzialnością
Wartości statusu zapisu poza zdefiniowanym niezerowym zakresem statusów oraz zerowe albo nadmierne udane liczby bajtów stają się HPDF_STATUS_IO_ERROR; layout rekordu V1 i zachowanie częściowych udanych zapisów pozostają niezmienione
Status i cykl życia
| Status | Znaczenie |
|---|---|
HPDF_STATUS_OK | Operacja się zakończyła |
HPDF_STATUS_INVALID_ARGUMENT | Brak wymaganego wskaźnika lub wywołania zwrotnego albo zakres bajtów jest nieprawidłowy |
HPDF_STATUS_INVALID_HANDLE | Uchwyt jest nullem, nieznany albo już zniszczony |
HPDF_STATUS_INCOMPATIBLE_ABI | Rozmiar struktury, wersja lub flagi są nieobsługiwane |
HPDF_STATUS_CANCELLED | Wywołanie zwrotne anulowania zażądało zakończenia |
HPDF_STATUS_IO_ERROR | Wywołanie zwrotne wejścia lub wyjścia zawiodło albo naruszyło swój kontrakt liczbowy |
HPDF_STATUS_PARSE_ERROR | Wejście zostało odczytane poprawnie, ale nie zostało zaakceptowane jako PDF |
HPDF_STATUS_INTERNAL_ERROR | Wewnętrzna awaria została przechwycona, zanim przekroczyła ABI |
Każde udane hpdf_document_create musi mieć parę w postaci jednego udanego hpdf_document_destroy; powtórzone niszczenie zwraca HPDF_STATUS_INVALID_HANDLE
Nieprzezroczyste uchwyty to monotoniczne tokeny lokalne dla procesu, a nie adresy obiektów, więc ponowne użycie alokatora nie wskrzesi nieaktualnego uchwytu
Wyjątki nigdy nie przekraczają granicy C, a opcjonalne wywołanie zwrotne diagnostyki otrzymuje odpowiadające bajty komunikatu, zanim operacja zwróci status błędu
Współbieżność
Różne uchwyty mogą być używane współbieżnie, ale wywołujący muszą szeregować operacje i niszczenie dla tego samego uchwytu
Starsze wywołania zwrotne Pascal
THPDFABICallbacks i pomocniki Pascal HPDFDoc* pozostają zgodne na poziomie źródeł dla aplikacji Delphi i C++Builder, ale natywne integracje C powinny używać hotpdf_abi.h i małoliterowych eksportów v1