HotPDF 穩定 C 回呼 ABI
HotPDFABI.dll 公開扁平的 cdecl 函式,具有固定寬度的狀態值、不透明控制代碼、明確的位元組長度,以及在 Lib/hotpdf_abi.h 中宣告的版本化 hpdf_io_v1 回呼結構
建置輸出
執行 build-HotPDF-ABI.cmd,即可在 Lib/ABI/<platform>/Release 下建置 Win32 與 Win64 DLL 以及匯入程式庫
公開 ABI 使用穩定的小寫匯出名稱,而 hpdf_abi_version 與 hpdf_abi_io_v1_size 讓呼叫端在建立文件之前先驗證契約
核心函式
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);
版本化 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 在 Win32 上是 48 位元組、Win64 上是 72 位元組,flags 在 ABI v1 必須為零,而更大的未來結構不必猜測欄位版面就能區分
所有回呼與匯出函式都使用 cdecl,每個文字指標都帶有明確的位元組長度,而且沒有任何 Delphi 字串、類別、介面、列舉、例外或 Boolean 跨越邊界
隨機存取輸入
read_at 接收絕對 64 位元偏移並直接寫入解析器的目的地緩衝區,而 get_size 在來源附加時一次性回報不可變的來源大小
部分成功的讀取會被接受,並透過重複的回呼呼叫完成,因此範圍存放區與有界的網路讀取器不必配置中繼的完整檔案緩衝區
回呼狀態與來源位元組必須保持有效,直到文件控制代碼被摧毀,或另一個來源被載入該控制代碼
串流輸出
write 直接從 SaveLoadedDocumentToStream 接收循序輸出分塊;部分成功的寫入會一直重試,直到完整分塊被接受
零位元組的成功寫入會被當成 I/O 錯誤拒絕,因為它無法向前推進
對 JSON execute 與雙 handle 比較操作,寫 callback 失敗後不會再次透過同一 writer 與 user-data 對發布錯誤結果,包括 OutputIO 和 ResultIO 共用該對的情況;呼叫端已收到的部分候選位元組仍由呼叫端自行負責
寫入狀態值超出已定義的非零狀態範圍、成功位元組數為零或超額時,都會變成 HPDF_STATUS_IO_ERROR;V1 記錄版面與成功的部分寫入行為保持不變
狀態與生命週期
| 狀態 | 意義 |
|---|---|
HPDF_STATUS_OK | 作業已完成 |
HPDF_STATUS_INVALID_ARGUMENT | 必要的指標或回呼缺席,或位元組範圍無效 |
HPDF_STATUS_INVALID_HANDLE | 控制代碼為 null、未知或已摧毀 |
HPDF_STATUS_INCOMPATIBLE_ABI | 結構大小、版本或旗標不受支援 |
HPDF_STATUS_CANCELLED | 取消回呼要求終止 |
HPDF_STATUS_IO_ERROR | 輸入或輸出回呼失敗,或違反其數量契約 |
HPDF_STATUS_PARSE_ERROR | 輸入讀取成功,但未被接受為 PDF |
HPDF_STATUS_INTERNAL_ERROR | 內部失敗在跨越 ABI 之前就被攔截 |
每次成功的 hpdf_document_create 都必須配對一次成功的 hpdf_document_destroy;重複摧毀會回傳 HPDF_STATUS_INVALID_HANDLE
不透明控制代碼是單調遞增的程序區域符記,而不是物件位址,因此配置器重用無法復活過期的控制代碼
例外永遠不會跨越 C 邊界,而選用的診斷回呼會在作業回傳錯誤狀態之前收到對應的訊息位元組
並行
不同的控制代碼可以並行使用,但同一個控制代碼的作業與摧毀必須由呼叫端序列化
舊版 Pascal 回呼
THPDFABICallbacks 與 HPDFDoc* Pascal 輔助程式對 Delphi 與 C++Builder 應用程式保持原始碼相容,但原生 C 整合應使用 hotpdf_abi.h 與小寫的 v1 匯出