Skip to content

Commit f1d8845

Browse files
committed
f readme - use headers suggested by jeff
1 parent 77496db commit f1d8845

File tree

1 file changed

+151
-146
lines changed

1 file changed

+151
-146
lines changed

lightning-c-bindings/README.md

Lines changed: 151 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -8,158 +8,163 @@ In other words, if you're reading this, you're either writing bindings for a new
88
you're in the wrong place - individual language bindings should come with their own documentation.
99

1010
LDK C Bindings
11-
===================
11+
==============
1212

1313
The C bindings available at include/lightning.h require inclusion of include/rust_types.h first.
1414

1515
All of the Rust-Lightning types are mapped into C equivalents which take a few forms, with the C
1616
type getting an `LDK` prefix to their native Rust type names.
1717

18-
* Structs are mapped into a simple wrapper containing a pointer to the native Rust-Lightning
19-
object and a flag to indicate whether the object is owned or only a reference. Such mappings
20-
usually generate a `X_free` function which must be called to release the allocated resources.
21-
Note that calling `X_free` will do nothing if the underlying pointer is NULL or if the reference
22-
flag is set.
23-
24-
You MUST NOT create such wrapper structs manually, relying instead on constructors which have
25-
been mapped from equivalent Rust constructors.
26-
27-
Note that, thanks to the is-reference flag and the pointer being NULLable, such structs
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.
32-
33-
For example, this is the mapping of ChannelManager.
34-
```c
35-
typedef struct MUST_USE_STRUCT LDKChannelManager {
36-
/** ... */
37-
LDKnativeChannelManager *inner;
38-
bool _underlying_ref;
39-
} LDKChannelManager;
40-
```
41-
42-
* Traits are mapped into a concrete struct containing a void pointer (named `this_arg` and a jump
43-
table listing the functions which the trait must implement. The void pointer may be set to any
44-
value and is never interpreted (or dereferenced) by the bindings logic in any way. It is passed
45-
as the first argument to all function calls in the trait. You may wish to use it as a pointer to
46-
your own internal data structure, though it may also occasionally make sense to e.g. cast a file
47-
descriptor into a void pointer and use it to track a socket.
48-
49-
This should remind you of a C++ vtable, only written out by hand and with the class only
50-
containing a pointer, instead of the regular class data.
51-
52-
Each trait additionally contains `free` and `clone` function pointers, which may be NULL. The
53-
`free` function is passed the void pointer when the object is `Drop`ed in Rust. The `clone`
54-
function is passed the void pointer when the object is `Clone`ed in Rust, returning a new void
55-
pointer for the new object. If the `free` pointer is NULL, you will not receive any notification
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`
58-
without implementing `clone`, you will likely end up with use-after-free bugs.
59-
60-
For example, `LDKSocketDescriptor` is mapped as follows:
61-
```c
62-
typedef struct LDKSocketDescriptor {
63-
void *this_arg;
64-
/** ... */
65-
uintptr_t (*send_data)(void *this_arg, LDKu8slice data, bool resume_read);
66-
/** ... */
67-
void (*disconnect_socket)(void *this_arg);
68-
bool (*eq)(const void *this_arg, const void *other_arg);
69-
uint64_t (*hash)(const void *this_arg);
70-
void *(*clone)(const void *this_arg);
71-
void (*free)(void *this_arg);
72-
} LDKSocketDescriptor;
73-
```
74-
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:
80-
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
86-
variants which contain payloads. Such enums are mapped automatically by cbindgen as a tag which
87-
indicates the type and a union which holds the relevant fields for a given tag. An `X_free`
88-
function is provided for the enum as a whole which automatically frees the correct fields for a
89-
given tag, and a `Sentinel` tag is provided which causes the free function to do nothing (but
90-
which must never appear in an enum when accessed by Rust code). The `Sentinel` tag is used by
91-
the C++ wrapper classes to allow moving the ownership of an enum while invalidating the old copy.
92-
93-
For example, the unitary enum `LDKChannelMonitorUpdateErr` is mapped as follows:
94-
```c
95-
typedef enum LDKChannelMonitorUpdateErr {
96-
/** .. */
97-
LDKChannelMonitorUpdateErr_TemporaryFailure,
98-
/** .. */
99-
LDKChannelMonitorUpdateErr_PermanentFailure,
100-
/** .. */
101-
LDKChannelMonitorUpdateErr_Sentinel,
102-
} LDKChannelMonitorUpdateErr;
103-
```
104-
105-
and the non-unitary enum LDKErrorAction is mapped as follows:
106-
```c
107-
typedef enum LDKErrorAction_Tag {
108-
/** .. */
109-
LDKErrorAction_DisconnectPeer,
110-
/** .. */
111-
LDKErrorAction_IgnoreError,
112-
/** .. */
113-
LDKErrorAction_SendErrorMessage,
114-
/** .. */
115-
LDKErrorAction_Sentinel,
116-
} LDKErrorAction_Tag;
117-
118-
typedef struct LDKErrorAction_LDKDisconnectPeer_Body {
119-
LDKErrorMessage msg;
120-
} LDKErrorAction_LDKDisconnectPeer_Body;
121-
122-
typedef struct LDKErrorAction_LDKSendErrorMessage_Body {
123-
LDKErrorMessage msg;
124-
} LDKErrorAction_LDKSendErrorMessage_Body;
125-
126-
typedef struct LDKErrorAction {
127-
LDKErrorAction_Tag tag;
128-
union {
129-
LDKErrorAction_LDKDisconnectPeer_Body disconnect_peer;
130-
LDKErrorAction_LDKSendErrorMessage_Body send_error_message;
131-
};
132-
} LDKErrorAction;
133-
```
134-
135-
* Struct member functions are mapped as `Struct_function_name` and take a pointer to the mapped
136-
struct as their first argument. Free-standing functions are mapped simply as `function_name` and
137-
take the relevant mapped type arguments.
138-
139-
Functions which return `&OpaqueRustType` and which return `OpaqueRustType` are both mapped to a
140-
function returning an owned wrapper struct. The `_underlying_ref` flag (see above) will be set
141-
to indicate that the pointed-to Rust object is owned or only a reference. Thus, when
142-
implementing a function which Rust will call or calling a Rust function, you should check the
143-
Rust documentation for the function to determine whether an owned or referenced object is
144-
expected or returned.
145-
146-
Similarly, when a function takes an `Option<RustType>` as a parameter or a return value, the C
147-
type is the same as if it took only `RustType`, with the `inner` field set to NULL to indicate
148-
None. For example, `ChannelManager_create_channel` takes an `Option<LDKUserConfig>` not an
149-
`LDKUserConfig`, but its definition is:
150-
```c
151-
MUST_USE_RES ... ChannelManager_create_channel(const LDKChannelManager *this_arg, ..., LDKUserConfig override_config);
152-
```
153-
154-
* Various containers (Tuples, Vecs, Results, etc) are mapped into C structs of the form
155-
`LDKCContainerType_ContainerElementsZ`. Inner fields are often pointers, and in the case of
156-
primitive types, these may be allocated in C using the system allocator. See [the Rust docs on
157-
your platform's default System allocator](https://doc.rust-lang.org/std/alloc/struct.System.html)
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>), ()>`.
162-
18+
#### Structs
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 reference flag is set.
23+
24+
You MUST NOT create such wrapper structs manually, relying instead on constructors which have been
25+
mapped from equivalent Rust constructors.
26+
27+
Note that, thanks to the is-reference flag and the pointer being NULLable, such structs effectively
28+
represent `RustType`, `&RustType`, and `Option<RustType>`. Check the corresponding Rust
29+
documentation for the function or struct you are using to ensure you use the correct call semantics.
30+
The passed struct must match the call semantics or an assertion failure or NULL pointer dereference
31+
may occur.
32+
33+
For example, this is the mapping of ChannelManager.
34+
```c
35+
typedef struct MUST_USE_STRUCT LDKChannelManager {
36+
/** ... */
37+
LDKnativeChannelManager *inner;
38+
bool _underlying_ref;
39+
} LDKChannelManager;
40+
```
41+
42+
#### Traits
43+
Traits are mapped into a concrete struct containing a void pointer (named `this_arg` and a jump
44+
table listing the functions which the trait must implement. The void pointer may be set to any value
45+
and is never interpreted (or dereferenced) by the bindings logic in any way. It is passed as the
46+
first argument to all function calls in the trait. You may wish to use it as a pointer to your own
47+
internal data structure, though it may also occasionally make sense to e.g. cast a file descriptor
48+
into a void pointer and use it to track a socket.
49+
50+
This should remind you of a C++ vtable, only written out by hand and with the class only containing
51+
a pointer, instead of the regular class data.
52+
53+
Each trait additionally contains `free` and `clone` function pointers, which may be NULL. The `free`
54+
function is passed the void pointer when the object is `Drop`ed in Rust. The `clone` function is
55+
passed the void pointer when the object is `Clone`ed in Rust, returning a new void pointer for the
56+
new object. If the `free` pointer is NULL, you will not receive any notification when the trait
57+
object is no longer needed. If the `clone` pointer is NULL, we assume that the trait object may be
58+
`memcpy()`'d to create copies. Note that if you release resources with `free` without implementing
59+
`clone`, you will likely end up with use-after-free bugs.
60+
61+
For example, `LDKSocketDescriptor` is mapped as follows:
62+
```c
63+
typedef struct LDKSocketDescriptor {
64+
void *this_arg;
65+
/** ... */
66+
uintptr_t (*send_data)(void *this_arg, LDKu8slice data, bool resume_read);
67+
/** ... */
68+
void (*disconnect_socket)(void *this_arg);
69+
bool (*eq)(const void *this_arg, const void *other_arg);
70+
uint64_t (*hash)(const void *this_arg);
71+
void *(*clone)(const void *this_arg);
72+
void (*free)(void *this_arg);
73+
} LDKSocketDescriptor;
74+
```
75+
76+
##### Rust Trait Implementations
77+
Rust structs that implement a trait result in the generation of an `X_as_Y` function, which takes a
78+
C struct wrapping the Rust native object and returns a generated trait object. Such generated
79+
objects are only valid as long as the original Rust native object has not been `free`'d or moved as
80+
a part of a Rust function call (ie continues to be owned by the C struct). For example, to use an
81+
`LDKInMemoryChannelKeys` as a `ChannelKeys`, `InMemoryChannelKeys_as_ChannelKeys` is exposed:
82+
83+
```c
84+
LDKChannelKeys InMemoryChannelKeys_as_ChannelKeys(const LDKInMemoryChannelKeys *this_arg);
85+
```
86+
87+
#### Enums
88+
Rust "unitary" enums are mapped simply as an equivalent C enum; however, some Rust enums have
89+
variants which contain payloads. Such enums are mapped automatically by cbindgen as a tag which
90+
indicates the type and a union which holds the relevant fields for a given tag. An `X_free` function
91+
is provided for the enum as a whole which automatically frees the correct fields for a give tag, and
92+
a `Sentinel` tag is provided which causes the free function to do nothing (but which must never
93+
appear in an enum when accessed by Rust code). The `Sentinel` tag is used by the C++ wrapper classes
94+
to allow moving the ownership of an enum while invalidating the old copy.
95+
96+
For example, the unitary enum `LDKChannelMonitorUpdateErr` is mapped as follows:
97+
```c
98+
typedef enum LDKChannelMonitorUpdateErr {
99+
/** .. */
100+
LDKChannelMonitorUpdateErr_TemporaryFailure,
101+
/** .. */
102+
LDKChannelMonitorUpdateErr_PermanentFailure,
103+
/** .. */
104+
LDKChannelMonitorUpdateErr_Sentinel,
105+
} LDKChannelMonitorUpdateErr;
106+
```
107+
108+
and the non-unitary enum LDKErrorAction is mapped as follows:
109+
```c
110+
typedef enum LDKErrorAction_Tag {
111+
/** .. */
112+
LDKErrorAction_DisconnectPeer,
113+
/** .. */
114+
LDKErrorAction_IgnoreError,
115+
/** .. */
116+
LDKErrorAction_SendErrorMessage,
117+
/** .. */
118+
LDKErrorAction_Sentinel,
119+
} LDKErrorAction_Tag;
120+
121+
typedef struct LDKErrorAction_LDKDisconnectPeer_Body {
122+
LDKErrorMessage msg;
123+
} LDKErrorAction_LDKDisconnectPeer_Body;
124+
125+
typedef struct LDKErrorAction_LDKSendErrorMessage_Body {
126+
LDKErrorMessage msg;
127+
} LDKErrorAction_LDKSendErrorMessage_Body;
128+
129+
typedef struct LDKErrorAction {
130+
LDKErrorAction_Tag tag;
131+
union {
132+
LDKErrorAction_LDKDisconnectPeer_Body disconnect_peer;
133+
LDKErrorAction_LDKSendErrorMessage_Body send_error_message;
134+
};
135+
} LDKErrorAction;
136+
```
137+
138+
#### Functions
139+
Struct member functions are mapped as `Struct_function_name` and take a pointer to the mapped struct
140+
as their first argument. Free-standing functions are mapped simply as `function_name` and take the
141+
relevant mapped type arguments.
142+
143+
Functions which return `&OpaqueRustType` and which return `OpaqueRustType` are both mapped to a
144+
function returning an owned wrapper struct. The `_underlying_ref` flag (see above) will be set to
145+
indicate that the pointed-to Rust object is owned or only a reference. Thus, when implementing a
146+
function which Rust will call or calling a Rust function, you should check the Rust documentation
147+
for the function to determine whether an owned or referenced object is expected or returned.
148+
149+
Similarly, when a function takes an `Option<RustType>` as a parameter or a return value, the C type
150+
is the same as if it took only `RustType`, with the `inner` field set to NULL to indicate None. For
151+
example, `ChannelManager_create_channel` takes an `Option<LDKUserConfig>` not an `LDKUserConfig`,
152+
but its definition is:
153+
```c
154+
MUST_USE_RES ... ChannelManager_create_channel(const LDKChannelManager *this_arg, ..., LDKUserConfig override_config);
155+
```
156+
157+
#### Containers
158+
Various containers (Tuples, Vecs, Results, etc) are mapped into C structs of the form
159+
`LDKCContainerType_ContainerElementsZ`. Inner fields are often pointers, and in the case of
160+
primitive types, these may be allocated in C using the system allocator. See [the Rust docs on your
161+
platform's default System allocator](https://doc.rust-lang.org/std/alloc/struct.System.html) for
162+
which allocator you must use. $ecursive containers are possible, and simply replace the
163+
`ContainerElements` part with `InnerContainerType_InnerContainerElementsZ`, eg
164+
`LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ` represents a
165+
`Result<(Signature, Vec<Signature>), ()>`.
166+
167+
#### Notes
163168
As the bindings are auto-generated, the best resource for documentation on them is the native Rust
164169
docs available via `cargo doc` or [docs.rs/lightning](https://docs.rs/lightning).
165170

0 commit comments

Comments
 (0)