Automatic Binding¶
This section is an attempt to put into practice an idea presented by by Andre Weissflog in its post entitled Automatic Language Bindings. The main goal is to derive a C++ wrapper from my library’s public API.
To do so, I performed three steps (serving as a TLDR too):
Using clang to generate a JSON file containing the Abstract Syntax Tree
Cleaning AST to generate lighter JSON files
Generating a C++ header wrapping C functions and handles
AST Generation¶
Here’s the clang
command to generate a JSON abstract syntax tree from a single header.
clang -Xclang
-ast-dump=json
-fsyntax-only
-c {your-header}
-I/{include_directories}
> {header-ast}.json
The generated JSON needs to be cleaned as it contains too much noise.
It can be done using python
and its already included json
module.
I wrap each step using cmake targets yielding a streamlined pipeline:
# Generate the AST
cmake --build . --target haiku-ast
# Cleaning AST to generate two other json files
cmake --build . --target haiku-filter
# Generating C++ wrapper header file
cmake --build . --target haiku-bindgen
Converting C-API into C++ objects¶
hk_buffer_t result = hkgfx_buffer_create(device, &(hk_gfx_buffer_desc){
.bytesize = 20*sizeof(uint32_t),
.usage_flags = HK_BUFFER_USAGE_TRANSFER_SRC_BIT | HK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
.memory_type = HK_MEMORY_TYPE_GPU_TO_CPU
});
As C++20 designated-initializers are not as convenient as in C99, I chose to wrap descriptor data structures in a builder pattern. Translating the previous buffer creation snippet to C++ yields:
HkBuffer ssbo = gfx::HkBufferDesc()
.set_bytesize(20*sizeof(uint32_t))
.set_usage_flags(HK_BUFFER_USAGE_TRANSFER_SRC_BIT | HK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
.set_memory_type(HK_MEMORY_TYPE_GPU_TO_CPU)
.create(device);