1 The wrapper crate and C/C++ Headers in this folder are auto-generated from the Rust-Lightning
2 source by the c-bindings-gen crate contained in the source tree and
3 [cbindgen](https://github.com/eqrion/cbindgen). They are intended to be used as a base for building
4 language-specific bindings, and are thus incredibly low-level and may be difficult to work with
7 In other words, if you're reading this, you're either writing bindings for a new language, or
8 you're in the wrong place - individual language bindings should come with their own documentation.
13 The C bindings available at include/lightning.h require inclusion of include/rust_types.h first.
15 All of the Rust-Lightning types are mapped into C equivalents which take a few forms, with the C
16 type getting an `LDK` prefix to their native Rust type names.
19 Structs are mapped into a simple wrapper containing a pointer to the native Rust-Lightning object
20 and a flag to indicate whether the object is owned or only a reference. Such mappings usually
21 generate a `X_free` function which must be called to release the allocated resources. Note that
22 calling `X_free` will do nothing if the underlying pointer is NULL or if the `is_owned` flag is not
25 You MUST NOT create such wrapper structs manually, relying instead on constructors which have been
26 mapped from equivalent Rust constructors.
28 Note that, thanks to the is-owned flag and the pointer being NULLable, such structs effectively
29 represent `RustType`, `&RustType`, and `Option<RustType>`. Check the corresponding Rust
30 documentation for the function or struct you are using to ensure you use the correct call semantics.
31 The passed struct must match the call semantics or an assertion failure or NULL pointer dereference
34 For example, this is the mapping of ChannelManager.
36 typedef struct MUST_USE_STRUCT LDKChannelManager {
38 LDKnativeChannelManager *inner;
44 Traits are mapped into a concrete struct containing a void pointer (named `this_arg` and a jump
45 table listing the functions which the trait must implement. The void pointer may be set to any value
46 and is never interpreted (or dereferenced) by the bindings logic in any way. It is passed as the
47 first argument to all function calls in the trait. You may wish to use it as a pointer to your own
48 internal data structure, though it may also occasionally make sense to e.g. cast a file descriptor
49 into a void pointer and use it to track a socket.
51 This should remind you of a C++ vtable, only written out by hand and with the class only containing
52 a pointer, instead of the regular class data.
54 Each trait additionally contains `free` and `clone` function pointers, which may be NULL. The `free`
55 function is passed the void pointer when the object is `Drop`ed in Rust. The `clone` function is
56 passed the void pointer when the object is `Clone`ed in Rust, returning a new void pointer for the
57 new object. If the `free` pointer is NULL, you will not receive any notification when the trait
58 object is no longer needed. If the `clone` pointer is NULL, we assume that the trait object may be
59 `memcpy()`'d to create copies. Note that if you release resources with `free` without implementing
60 `clone`, you will likely end up with use-after-free bugs (as copies of the original this_arg value
61 may still exist, unbeknownst to you).
63 For example, `LDKSocketDescriptor` is mapped as follows:
65 typedef struct LDKSocketDescriptor {
68 uintptr_t (*send_data)(void *this_arg, LDKu8slice data, bool resume_read);
70 void (*disconnect_socket)(void *this_arg);
71 bool (*eq)(const void *this_arg, const void *other_arg);
72 uint64_t (*hash)(const void *this_arg);
73 void *(*clone)(const void *this_arg);
74 void (*free)(void *this_arg);
75 } LDKSocketDescriptor;
78 ##### Rust Trait Implementations
79 Rust structs that implement a trait result in the generation of an `X_as_Y` function, which takes a
80 C struct wrapping the Rust native object and returns a generated trait object. Such generated
81 objects are only valid as long as the original Rust native object has not been `free`'d or moved as
82 a part of a Rust function call (ie continues to be owned by the C struct). For example, to use an
83 `LDKInMemoryChannelKeys` as a `ChannelKeys`, `InMemoryChannelKeys_as_ChannelKeys` is exposed:
86 LDKChannelKeys InMemoryChannelKeys_as_ChannelKeys(const LDKInMemoryChannelKeys *this_arg);
90 Rust "unitary" enums are mapped simply as an equivalent C enum; however, some Rust enums have
91 variants which contain payloads. Such enums are mapped automatically by cbindgen as a tag which
92 indicates the type and a union which holds the relevant fields for a given tag. An `X_free` function
93 is provided for the enum as a whole which automatically frees the correct fields for a give tag, and
94 a `Sentinel` tag is provided which causes the free function to do nothing (but which must never
95 appear in an enum when accessed by Rust code). The `Sentinel` tag is used by the C++ wrapper classes
96 to allow moving the ownership of an enum while invalidating the old copy.
98 For example, the unitary enum `LDKChannelMonitorUpdateErr` is mapped as follows:
100 typedef enum LDKChannelMonitorUpdateErr {
102 LDKChannelMonitorUpdateErr_TemporaryFailure,
104 LDKChannelMonitorUpdateErr_PermanentFailure,
106 LDKChannelMonitorUpdateErr_Sentinel,
107 } LDKChannelMonitorUpdateErr;
110 and the non-unitary enum LDKErrorAction is mapped as follows:
112 typedef enum LDKErrorAction_Tag {
114 LDKErrorAction_DisconnectPeer,
116 LDKErrorAction_IgnoreError,
118 LDKErrorAction_SendErrorMessage,
120 LDKErrorAction_Sentinel,
121 } LDKErrorAction_Tag;
123 typedef struct LDKErrorAction_LDKDisconnectPeer_Body {
125 } LDKErrorAction_LDKDisconnectPeer_Body;
127 typedef struct LDKErrorAction_LDKSendErrorMessage_Body {
129 } LDKErrorAction_LDKSendErrorMessage_Body;
131 typedef struct LDKErrorAction {
132 LDKErrorAction_Tag tag;
134 LDKErrorAction_LDKDisconnectPeer_Body disconnect_peer;
135 LDKErrorAction_LDKSendErrorMessage_Body send_error_message;
141 Struct member functions are mapped as `Struct_function_name` and take a pointer to the mapped struct
142 as their first argument. Free-standing functions are mapped simply as `function_name` and take the
143 relevant mapped type arguments.
145 Functions which return `&OpaqueRustType` and which return `OpaqueRustType` are both mapped to a
146 function returning an owned wrapper struct. The `is_owned` flag (see above) will be set to indicate
147 that the pointed-to Rust object is owned or only a reference. Thus, when implementing a function
148 which Rust will call or calling a Rust function, you should check the Rust documentation for the
149 function to determine whether an owned or referenced object is expected or returned.
151 Similarly, when a function takes an `Option<RustType>` as a parameter or a return value, the C type
152 is the same as if it took only `RustType`, with the `inner` field set to NULL to indicate None. For
153 example, `ChannelManager_create_channel` takes an `Option<LDKUserConfig>` not an `LDKUserConfig`,
154 but its definition is:
156 MUST_USE_RES ... ChannelManager_create_channel(const LDKChannelManager *this_arg, ..., LDKUserConfig override_config);
160 Various containers (Tuples, Vecs, Results, etc) are mapped into C structs of the form
161 `LDKCContainerType_ContainerElementsZ`. Inner fields are often pointers, and in the case of
162 primitive types, these may be allocated in C using the system allocator. See [the Rust docs on your
163 platform's default System allocator](https://doc.rust-lang.org/std/alloc/struct.System.html) for
164 which allocator you must use. Recursive containers are possible, and simply replace the
165 `ContainerElements` part with `InnerContainerType_InnerContainerElementsZ`, eg
166 `LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ` represents a
167 `Result<(Signature, Vec<Signature>), ()>`.
170 As the bindings are auto-generated, the best resource for documentation on them is the native Rust
171 docs available via `cargo doc` or [docs.rs/lightning](https://docs.rs/lightning).
173 The memory model is largely the Rust memory model and not a native C-like memory model. Thus,
174 function parameters are largely only ever passed by reference or by move, with pass-by-copy
175 semantics only applying to primitive types. However, because the underlying types are largely
176 pointers, the same function signature may imply two different memory ownership semantics. Thus, you
177 MUST read the Rust documentation while using the C bindings. For functions which take arguments
178 where ownership is moved to the function scope, the corresponding `X_free` function MUST NOT be
179 called on the object, whereas for all other objects, `X_free` MUST be used to free resources.
184 The C++ bindings available at include/lightningpp.hpp require extern "C" inclusion of lightning.h
185 and rust_types.h first. They represent thin wrappers around the C types which provide a few
186 C++-isms to make memory model correctness easier to achieve. They provide:
187 * automated destructors which call the relevant `X_free` C functions,
188 * move constructors both from C++ classes and the original C struct, with the original object
189 cleared to ensure destruction/`X_free` calls do not cause a double-free.
190 * Move semantics via the () operator, returning the original C struct and clearing the C++ object.
191 This allows calls such as `C_function(cpp_object)` which work as expected with move semantics.
193 In general, you should prefer to use the C++ bindings if possible, as they make memory leaks and
194 other violations somewhat easier to avoid. Note that, because the C functions are not redefined in
195 C++, all functions return the C type. Thus, you must bind returned values to the equivalent C++ type
196 (replacing `LDKX` with `LDK::X`) to ensure the destructor is properly run. A demonstration of such
197 usage is available at [demo.cpp](demo.cpp).
202 There are a few gotchas around future changes to Rust-Lightning which the bindings may not support.
204 * Any trait method which returns a reference to a struct or inner variable cannot be called in
205 parallel. This is because such functions always return a local variable stored inside the trait,
206 with a call through a function pointer to get the local variable set correctly. Automatically
207 generated setter functions have comments describing the potential race conditions in their
210 For example, the `ChannelKeys::pubkeys() -> &ChannelPublicKeys` function is mapped as this:
213 typedef struct LDKChannelKeys {
215 LDKChannelPublicKeys pubkeys;
217 void (*set_pubkeys)(const LDKChannelKeys*);
222 **It is highly recommended that you test any code which relies on the C (or C++) bindings in
223 valgrind, AddressSanitizer, MemorySanitizer, or other similar tools to ensure correctness.**
228 `genbindings.sh` is currently a catch-all script for bindings - it generates the latest Rust/C/C++
229 code for bindings from the rust-lightning source code, builds it, and then runs various test apps.
231 Note that after running `genbindings.sh`, if possible, the static lib in target/debug (eg
232 target/debug/liblightning.a) will be linked with address sanitizer. In order to build against it,
233 you will need to link with `clang` with `-fsanitize=address` with the same version of LLVM as
234 `rustc`'s LLVM. If `genbindings.sh` failed to find a matching `clang` or you are building on an
235 unsupported platform, a warning noting that address sanitizer is not available will be printed.