Quickstart
Create your first PDF document in a few lines of C code.
Prerequisites
Install Vanilla.PDF using one of the methods in the installation guide. The simplest option:
vcpkg install vanillapdf
Create a PDF document
The following example creates a PDF document with a single blank page and writes it to disk.
#include <stdio.h>
#include <vanillapdf/c_vanillapdf_api.h>
int main(void) {
DocumentHandle* document = NULL;
CatalogHandle* catalog = NULL;
PageTreeHandle* page_tree = NULL;
PageObjectHandle* page = NULL;
error_type rc;
/* Create a new document bound to an output path */
rc = Document_Create("output.pdf", &document);
if (rc != VANILLAPDF_ERROR_SUCCESS) { return 1; }
/* Navigate to the page tree via the root catalog */
rc = Document_GetCatalog(document, &catalog);
if (rc != VANILLAPDF_ERROR_SUCCESS) { goto cleanup; }
rc = Catalog_GetPages(catalog, &page_tree);
if (rc != VANILLAPDF_ERROR_SUCCESS) { goto cleanup; }
/* Create a blank page and append it */
rc = PageObject_CreateFromDocument(document, &page);
if (rc != VANILLAPDF_ERROR_SUCCESS) { goto cleanup; }
rc = PageTree_AppendPage(page_tree, page);
if (rc != VANILLAPDF_ERROR_SUCCESS) { goto cleanup; }
/* Write to disk */
rc = Document_Save(document, "output.pdf");
if (rc != VANILLAPDF_ERROR_SUCCESS) { goto cleanup; }
printf("Created output.pdf successfully.\n");
cleanup:
if (page) PageObject_Release(page);
if (page_tree) PageTree_Release(page_tree);
if (catalog) Catalog_Release(catalog);
if (document) Document_Release(document);
return (rc == VANILLAPDF_ERROR_SUCCESS) ? 0 : 1;
}
Key patterns to notice:
Single header –
<vanillapdf/c_vanillapdf_api.h>includes the entire C API.Handle-based – Every object is an opaque pointer (
DocumentHandle*,CatalogHandle*, etc.). The internal C++ implementation is never exposed.Error codes – Every function returns
error_type. Check againstVANILLAPDF_ERROR_SUCCESS.Manual cleanup – Each handle obtained from the library must be released. Initialize to
NULLand release in reverse order.
Build and run
Create a CMakeLists.txt:
cmake_minimum_required(VERSION 3.20)
project(QuickStart C)
find_package(vanillapdf CONFIG REQUIRED)
add_executable(quickstart main.c)
target_link_libraries(quickstart PRIVATE vanillapdf::vanillapdf)
Build:
cmake -S . -B build
cmake --build build
./build/quickstart # creates output.pdf
Sign the document
Use the CLI tool to add a digital signature:
vanillapdf-tools sign -s output.pdf -d signed.pdf -k private_key.p12 -p password
Verify it:
vanillapdf-tools verify -f signed.pdf
Query library version
error_type process_library_info() {
// Misc
string_type library_author = NULL;
// Version info
integer_type library_version_major = 0;
integer_type library_version_minor = 0;
integer_type library_version_patch = 0;
integer_type library_version_build = 0;
// Build time information
integer_type library_build_day = 0;
integer_type library_build_month = 0;
integer_type library_build_year = 0;
RETURN_ERROR_IF_NOT_SUCCESS(LibraryInfo_GetVersionMajor(&library_version_major));
RETURN_ERROR_IF_NOT_SUCCESS(LibraryInfo_GetVersionMinor(&library_version_minor));
RETURN_ERROR_IF_NOT_SUCCESS(LibraryInfo_GetVersionPatch(&library_version_patch));
RETURN_ERROR_IF_NOT_SUCCESS(LibraryInfo_GetVersionBuild(&library_version_build));
RETURN_ERROR_IF_NOT_SUCCESS(LibraryInfo_GetAuthor(&library_author));
RETURN_ERROR_IF_NOT_SUCCESS(LibraryInfo_GetBuildDay(&library_build_day));
RETURN_ERROR_IF_NOT_SUCCESS(LibraryInfo_GetBuildMonth(&library_build_month));
RETURN_ERROR_IF_NOT_SUCCESS(LibraryInfo_GetBuildYear(&library_build_year));
print_text("Library vanillapdf %d.%d.%d.%d by %s\n",
library_version_major,
library_version_minor,
library_version_patch,
library_version_build,
library_author
);
print_text("Built on %d.%d.%d\n",
library_build_day,
library_build_month,
library_build_year
);
return VANILLAPDF_TEST_ERROR_SUCCESS;
}
Retrieve error details
When a function returns an error code, extract the message:
error_type print_last_error() {
error_type error = 0;
char* error_message = NULL;
char* error_code_name = NULL;
size_type error_code_name_length = 0;
size_type error_message_length = 0;
RETURN_ERROR_IF_NOT_SUCCESS(Errors_GetLastError(&error));
// Last error message
RETURN_ERROR_IF_NOT_SUCCESS(Errors_GetLastErrorMessageLength(&error_message_length));
if (error_message_length >= SIZE_MAX) {
unsigned long long length_converted = error_message_length;
printf("Buffer size is too big: %llu bytes\n", length_converted);
return VANILLAPDF_TEST_ERROR_FAILURE;
}
error_message = (char*) calloc(error_message_length, sizeof(char));
if (NULL == error_message) {
unsigned long long length_converted = error_message_length;
printf("Could not allocate memory: %llu bytes\n", length_converted);
return VANILLAPDF_TEST_ERROR_FAILURE;
}
RETURN_ERROR_IF_NOT_SUCCESS(Errors_GetLastErrorMessage(error_message, error_message_length));
// error code name
RETURN_ERROR_IF_NOT_SUCCESS(Errors_GetPrintableErrorTextLength(error, &error_code_name_length));
if (error_code_name_length >= SIZE_MAX) {
unsigned long long length_converted = error_code_name_length;
printf("Buffer size is too big: %llu bytes\n", length_converted);
return VANILLAPDF_TEST_ERROR_FAILURE;
}
error_code_name = (char*) calloc(error_code_name_length, sizeof(char));
if (NULL == error_code_name) {
unsigned long long length_converted = error_code_name_length;
printf("Could not allocate memory: %llu bytes\n", length_converted);
return VANILLAPDF_TEST_ERROR_FAILURE;
}
RETURN_ERROR_IF_NOT_SUCCESS(Errors_GetPrintableErrorText(error, error_code_name, error_code_name_length));
if (error_message_length == 0) {
printf("Error %u (%s)\n", error, error_code_name);
} else {
printf("Error %u (%s): %s\n", error, error_code_name, error_message);
}
free(error_message);
free(error_code_name);
return VANILLAPDF_TEST_ERROR_SUCCESS;
}
Next steps
C API Guide – Handle system, memory management, error handling, debugging
Examples – Signing, merging, encryption, content stream processing
Signature Verification Guide – Verify digital signatures with trust stores
CLI Tools – All CLI commands: sign, verify, merge, extract, encrypt, decrypt
PDF Format Guide – Understand PDF syntax: objects, XRef tables, trailers