Download the native library
Choose the archive for your platform from the matching GitHub release. It contains the C++ wrapper, the underlying C header, shared and static libraries, relocatable CMake metadata, the ABI contract, and checksums.
find_package(Ironpress CONFIG REQUIRED)
target_link_libraries(your_target PRIVATE Ironpress::CXX)
Point CMAKE_PREFIX_PATH at the extracted archive. Use Ironpress::CXXStatic for static linkage. Both targets require C++17 and preserve the linked ABI check.
Create an HTML PDF
#include "ironpress.hpp"
#include <fstream>
int main() {
ironpress::Converter converter;
auto pdf = converter.convert_html("<h1>Hello from C++</h1>");
std::ofstream output("output.pdf", std::ios::binary);
output.write(reinterpret_cast<const char*>(pdf.data()),
static_cast<std::streamsize>(pdf.size()));
}
Converter and Pdf are move-only. Their destructors release the one native owner and never throw.
Render Markdown
Markdown returns the same uniquely owned PDF type:
auto pdf = converter.convert_markdown(
"# Release notes\n\nEverything shipped."
);
Reuse a configured converter
Configuration methods return the converter, so related settings stay readable and reusable.
converter
.set_page_size(ironpress::PageSize::letter)
.set_margins(ironpress::PageMargins::uniform(36.0F))
.set_compression(true)
.set_footer("Page {page} / {pages}");
auto first = converter.convert_html(first_html);
auto second = converter.convert_html(second_html);
Provide fonts as bytes
The C++ wrapper does not read document paths or access the network. Read a TrueType font or optional CJK or emoji pack in your application, then lend its bytes for one call.
std::vector<std::uint8_t> font = read_font();
converter.add_font("Inter", ironpress::BytesView(font));
Handle failures and runtime limits
Fallible methods throw ironpress::Error after the C call returns. Its status is stable and its message is copied before the native error owner is released.
try {
auto pdf = converter.convert_html(source);
} catch (const ironpress::Error& error) {
log(error.status(), error.what());
}
- No exception or Rust panic crosses the native boundary.
- A converter may move between threads while idle, but concurrent use is unsupported.
- Local paths, direct file output, async, streaming, and remote HTTP are absent.
- A moved-from owner may be destroyed or assigned a new owner.