@@ -25,15 +25,16 @@ type getting an `LDK` prefix to their native Rust type names.
25
25
been mapped from equivalent Rust constructors.
26
26
27
27
Note that, thanks to the is-reference flag and the pointer being NULLable, such structs
28
- effectively represent both ` &RustThing ` , ` RustThing ` , and ` Option<RustThing> ` . Check the
29
- corresponding Rust documentation for the function or struct you are using to ensure you use
30
- the correct call semantics.
28
+ effectively represent ` RustType ` , ` &RustType ` , and ` Option<RustType> ` . Check the corresponding
29
+ Rust documentation for the function or struct you are using to ensure you use the correct call
30
+ semantics. The passed struct must match the call semantics or an assertion failure or NULL
31
+ pointer dereference may occur.
31
32
32
33
For example, this is the mapping of ChannelManager.
33
- ```
34
+ ``` c
34
35
typedef struct MUST_USE_STRUCT LDKChannelManager {
35
36
/** ... */
36
- LDKlnChannelManager *inner;
37
+ LDKnativeChannelManager *inner;
37
38
bool _underlying_ref;
38
39
} LDKChannelManager;
39
40
```
@@ -48,16 +49,16 @@ type getting an `LDK` prefix to their native Rust type names.
48
49
This should remind you of a C++ vtable, only written out by hand and with the class only
49
50
containing a pointer, instead of the regular class data.
50
51
51
- Each trait additionally contains a ` free ` and ` clone ` function pointer , which may be NULL. The
52
+ Each trait additionally contains `free` and `clone` function pointers , which may be NULL. The
52
53
`free` function is passed the void pointer when the object is `Drop`ed in Rust. The `clone`
53
54
function is passed the void pointer when the object is `Clone`ed in Rust, returning a new void
54
55
pointer for the new object. If the `free` pointer is NULL, you will not receive any notification
55
- when the trait is no longer needed. If the ` clone ` pointer is NULL, we assume that the trait
56
- object may be ` memcpy() ` 'd to create copies. Note that if you release resources with ` free `
56
+ when the trait object is no longer needed. If the `clone` pointer is NULL, we assume that the
57
+ trait object may be `memcpy()`'d to create copies. Note that if you release resources with `free`
57
58
without implementing `clone`, you will likely end up with use-after-free bugs.
58
59
59
60
For example, `LDKSocketDescriptor` is mapped as follows:
60
- ```
61
+ ```c
61
62
typedef struct LDKSocketDescriptor {
62
63
void *this_arg;
63
64
/** ... */
@@ -71,21 +72,26 @@ type getting an `LDK` prefix to their native Rust type names.
71
72
} LDKSocketDescriptor;
72
73
```
73
74
74
- * Rust structs that implement a trait result in the generation of an ` X_as_Y ` function which allows
75
- you to use the native Rust object in place of the trait. Such generated objects are only valid as
76
- long as the original Rust native object is owned by a C-wrapped struct, and has not been ` free ` 'd
77
- or moved as a part of a Rust function call.
75
+ * Rust structs that implement a trait result in the generation of an ` X_as_Y ` function, which takes
76
+ a C struct wrapping the Rust native object and returns a generated trait object. Such generated
77
+ objects are only valid as long as the original Rust native object has not been ` free ` 'd or moved
78
+ as a part of a Rust function call (ie continues to be owned by the C struct). For example, to use
79
+ an ` LDKInMemoryChannelKeys ` as a ` ChannelKeys ` , ` InMemoryChannelKeys_as_ChannelKeys ` is exposed:
78
80
79
- * Rust "unitary" enums are mapped simply as an equivalent C enum, however some Rust enums have
81
+ ``` c
82
+ LDKChannelKeys InMemoryChannelKeys_as_ChannelKeys (const LDKInMemoryChannelKeys * this_arg);
83
+ ```
84
+
85
+ * Rust "unitary" enums are mapped simply as an equivalent C enum; however, some Rust enums have
80
86
variants which contain payloads. Such enums are mapped automatically by cbindgen as a tag which
81
- indicates the type and a union which holds the relevant fields for a given tag. A ` X_free `
87
+ indicates the type and a union which holds the relevant fields for a given tag. An `X_free`
82
88
function is provided for the enum as a whole which automatically frees the correct fields for a
83
89
given tag, and a `Sentinel` tag is provided which causes the free function to do nothing (but
84
90
which must never appear in an enum when accessed by Rust code). The `Sentinel` tag is used by
85
91
the C++ wrapper classes to allow moving the ownership of an enum while invalidating the old copy.
86
92
87
93
For example, the unitary enum `LDKChannelMonitorUpdateErr` is mapped as follows:
88
- ```
94
+ ```c
89
95
typedef enum LDKChannelMonitorUpdateErr {
90
96
/** .. */
91
97
LDKChannelMonitorUpdateErr_TemporaryFailure,
@@ -97,7 +103,7 @@ type getting an `LDK` prefix to their native Rust type names.
97
103
```
98
104
99
105
and the non-unitary enum LDKErrorAction is mapped as follows:
100
- ```
106
+ ``` c
101
107
typedef enum LDKErrorAction_Tag {
102
108
/** .. */
103
109
LDKErrorAction_DisconnectPeer,
@@ -126,29 +132,33 @@ type getting an `LDK` prefix to their native Rust type names.
126
132
} LDKErrorAction;
127
133
```
128
134
129
- * Struct member functions are mapped as ` Struct_function_name ` and take a reference to the mapped
135
+ * Struct member functions are mapped as `Struct_function_name` and take a pointer to the mapped
130
136
struct as their first argument. Free-standing functions are mapped simply as `function_name` and
131
137
take the relevant mapped type arguments.
132
138
133
139
Functions which return `&OpaqueRustType` and which return `OpaqueRustType` are both mapped to a
134
140
function returning an owned wrapper struct. The `_underlying_ref` flag (see above) will be set
135
141
to indicate that the pointed-to Rust object is owned or only a reference. Thus, when
136
142
implementing a function which Rust will call or calling a Rust function, you should check the
137
- Rust documentation for the function to determine which behavior is expected.
143
+ Rust documentation for the function to determine whether an owned or referenced object is
144
+ expected or returned.
138
145
139
146
Similarly, when a function takes an `Option<RustType>` as a parameter or a return value, the C
140
147
type is the same as if it took only `RustType`, with the `inner` field set to NULL to indicate
141
- None. For example, ` ChannelManager_create_channel ` takes an ` Option<LDKUserCOnfig > ` not an
148
+ None. For example, `ChannelManager_create_channel` takes an `Option<LDKUserConfig >` not an
142
149
`LDKUserConfig`, but its definition is:
143
- ```
144
- MUST_USE_RES LDKCResult_NoneAPIErrorZ ChannelManager_create_channel(const LDKChannelManager *this_arg, ..., LDKUserConfig override_config);
150
+ ```c
151
+ MUST_USE_RES ... ChannelManager_create_channel(const LDKChannelManager *this_arg, ..., LDKUserConfig override_config);
145
152
```
146
153
147
154
* Various containers (Tuples, Vecs, Results, etc) are mapped into C structs of the form
148
155
` LDKCContainerType_ContainerElementsZ ` . Inner fields are often pointers, and in the case of
149
156
primitive types, these may be allocated in C using the system allocator. See [ the Rust docs on
150
157
your platform's default System allocator] ( https://doc.rust-lang.org/std/alloc/struct.System.html )
151
- for which allocator you must use.
158
+ for which allocator you must use. $ecursive containers are possible, and simply replace the
159
+ ` ContainerElements ` part with ` InnerContainerType_InnerContainerElementsZ ` , eg
160
+ ` LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ ` represents a
161
+ ` Result<(Signature, Vec<Signature>), ()> ` .
152
162
153
163
As the bindings are auto-generated, the best resource for documentation on them is the native Rust
154
164
docs available via ` cargo doc ` or [ docs.rs/lightning] ( https://docs.rs/lightning ) .
@@ -171,7 +181,7 @@ C++-isms to make memory model correctness easier to achieve. They provide:
171
181
* move constructors both from C++ classes and the original C struct, with the original object
172
182
cleared to ensure destruction/` X_free ` calls do not cause a double-free.
173
183
* Move semantics via the () operator, returning the original C struct and clearing the C++ object.
174
- This allows calls such as ` C_function(cpp_object) ` which works as expected with move semantics.
184
+ This allows calls such as ` C_function(cpp_object) ` which work as expected with move semantics.
175
185
176
186
In general, you should prefer to use the C++ bindings if possible, as they make memory leaks and
177
187
other violations somewhat easier to avoid. Note that, because the C functions are not redefined in
@@ -189,5 +199,17 @@ These include:
189
199
with a call through a function pointer to get the local variable set correctly. Such functions
190
200
have comments describing the potential race conditions.
191
201
202
+ For example, the ` ChannelKeys::pubkeys() -> &ChannelPublicKeys ` function is mapped as this:
203
+
204
+ ``` c
205
+ typedef struct LDKChannelKeys {
206
+ ...
207
+ LDKChannelPublicKeys pubkeys;
208
+ /** ... */
209
+ void (* set_pubkeys)(const LDKChannelKeys* );
210
+ ...
211
+ } LDKChannelKeys;
212
+ ```
213
+
192
214
**It is highly recommended that you test any code which relies on the C (or C++) bindings in
193
215
valgrind, MemorySanitizer, or other similar tools to ensure correctness.**
0 commit comments