Skip to content

Commit 77496db

Browse files
committed
f readme - tons of tweaks from jeff and val
1 parent 978a8b0 commit 77496db

File tree

1 file changed

+46
-24
lines changed

1 file changed

+46
-24
lines changed

lightning-c-bindings/README.md

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,16 @@ type getting an `LDK` prefix to their native Rust type names.
2525
been mapped from equivalent Rust constructors.
2626

2727
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.
3132

3233
For example, this is the mapping of ChannelManager.
33-
```
34+
```c
3435
typedef struct MUST_USE_STRUCT LDKChannelManager {
3536
/** ... */
36-
LDKlnChannelManager *inner;
37+
LDKnativeChannelManager *inner;
3738
bool _underlying_ref;
3839
} LDKChannelManager;
3940
```
@@ -48,16 +49,16 @@ type getting an `LDK` prefix to their native Rust type names.
4849
This should remind you of a C++ vtable, only written out by hand and with the class only
4950
containing a pointer, instead of the regular class data.
5051
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
5253
`free` function is passed the void pointer when the object is `Drop`ed in Rust. The `clone`
5354
function is passed the void pointer when the object is `Clone`ed in Rust, returning a new void
5455
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`
5758
without implementing `clone`, you will likely end up with use-after-free bugs.
5859
5960
For example, `LDKSocketDescriptor` is mapped as follows:
60-
```
61+
```c
6162
typedef struct LDKSocketDescriptor {
6263
void *this_arg;
6364
/** ... */
@@ -71,21 +72,26 @@ type getting an `LDK` prefix to their native Rust type names.
7172
} LDKSocketDescriptor;
7273
```
7374

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:
7880

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
8086
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`
8288
function is provided for the enum as a whole which automatically frees the correct fields for a
8389
given tag, and a `Sentinel` tag is provided which causes the free function to do nothing (but
8490
which must never appear in an enum when accessed by Rust code). The `Sentinel` tag is used by
8591
the C++ wrapper classes to allow moving the ownership of an enum while invalidating the old copy.
8692
8793
For example, the unitary enum `LDKChannelMonitorUpdateErr` is mapped as follows:
88-
```
94+
```c
8995
typedef enum LDKChannelMonitorUpdateErr {
9096
/** .. */
9197
LDKChannelMonitorUpdateErr_TemporaryFailure,
@@ -97,7 +103,7 @@ type getting an `LDK` prefix to their native Rust type names.
97103
```
98104

99105
and the non-unitary enum LDKErrorAction is mapped as follows:
100-
```
106+
```c
101107
typedef enum LDKErrorAction_Tag {
102108
/** .. */
103109
LDKErrorAction_DisconnectPeer,
@@ -126,29 +132,33 @@ type getting an `LDK` prefix to their native Rust type names.
126132
} LDKErrorAction;
127133
```
128134
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
130136
struct as their first argument. Free-standing functions are mapped simply as `function_name` and
131137
take the relevant mapped type arguments.
132138
133139
Functions which return `&OpaqueRustType` and which return `OpaqueRustType` are both mapped to a
134140
function returning an owned wrapper struct. The `_underlying_ref` flag (see above) will be set
135141
to indicate that the pointed-to Rust object is owned or only a reference. Thus, when
136142
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.
138145
139146
Similarly, when a function takes an `Option<RustType>` as a parameter or a return value, the C
140147
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
142149
`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);
145152
```
146153

147154
* Various containers (Tuples, Vecs, Results, etc) are mapped into C structs of the form
148155
`LDKCContainerType_ContainerElementsZ`. Inner fields are often pointers, and in the case of
149156
primitive types, these may be allocated in C using the system allocator. See [the Rust docs on
150157
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>), ()>`.
152162

153163
As the bindings are auto-generated, the best resource for documentation on them is the native Rust
154164
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:
171181
* move constructors both from C++ classes and the original C struct, with the original object
172182
cleared to ensure destruction/`X_free` calls do not cause a double-free.
173183
* 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.
175185

176186
In general, you should prefer to use the C++ bindings if possible, as they make memory leaks and
177187
other violations somewhat easier to avoid. Note that, because the C functions are not redefined in
@@ -189,5 +199,17 @@ These include:
189199
with a call through a function pointer to get the local variable set correctly. Such functions
190200
have comments describing the potential race conditions.
191201

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+
192214
**It is highly recommended that you test any code which relies on the C (or C++) bindings in
193215
valgrind, MemorySanitizer, or other similar tools to ensure correctness.**

0 commit comments

Comments
 (0)