Skip to content

Commit c7e4727

Browse files
committed
More explanation on an example
1 parent 4cc4341 commit c7e4727

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

tests/convert/README.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Example of Conversion
2+
3+
## Files
4+
- [`lib.h`](lib.h) from the library to bind
5+
- [`generator/generator.ml`](generator/generator.ml) written by the user, describe the stub function and type to generate
6+
- [`mylib_stub.h`](mylib_stub.h) generated by camlid from `generator/generator.ml`, contains the definition of the generated type. Includes `lib.h`.
7+
- [`mylib_stub.c`](mylib_stub.c) generated by camlid from `generator/generator.ml`, contains the definition of the generated function stub. Includes `mylib_stub.h` and `defs.h`.
8+
- [`defs.h`](defs.h) written by the user. Includes `mylib_stub.h`.
9+
10+
## Explanation
11+
In this example a C function return some data in an argument if its return
12+
status is true. So the result of the corresponding function is an algebraic type:
13+
14+
```
15+
type result = | Data of int | Error of int
16+
```
17+
18+
This type is generated by camlid with the following corresponding C type and a translation function:
19+
20+
```
21+
typedef struct {
22+
enum { camlid_result_Data, camlid_result_Error} tag;
23+
union {
24+
struct { intptr_t data; } Data;
25+
struct { intptr_t error; } Error;} u; } camlid_result;
26+
```
27+
28+
Additionally, two C smart-constructors are defined:
29+
30+
```
31+
// @brief Fill [dst] with the constructor Data of result
32+
// @param dst structure to fill
33+
// @param data reference is assigned to the constructor field
34+
static inline void camlid_mk_result_Data(camlid_result* dst, intptr_t* data)
35+
36+
// @brief Fill [dst] with the constructor Error of result
37+
// @param dst structure to fill
38+
// @param error reference is assigned to the constructor field
39+
static inline void camlid_mk_result_Error(camlid_result* dst,
40+
intptr_t* error)
41+
```
42+
43+
So the user only need to define a function that takes the error and the data and fill a `camlid_result`:
44+
45+
```
46+
static void combine_data_or_status(camlid_result *dst, intptr_t *status, intptr_t *data)
47+
{
48+
if (*status)
49+
{
50+
camlid_mk_result_Error(dst, status);
51+
}
52+
else {
53+
camlid_mk_result_Data(dst, data);
54+
};
55+
}
56+
```

tests/convert/generator/generator.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ let result =
66
[ ("Data", [ ("data", int) ]); ("Error", [ ("error", int) ]) ]
77

88
let data, data_or_status =
9+
(* data_pc is a variable that will correspond to the C version of the parameter [data] in the stubbed function *)
910
let data, data_pc =
1011
Expert.simple_param ~input:false ~output:false (ptr_ref int) ~name:"data"
1112
in
13+
(* A conversion function takes normally two arguments a pointer to the destination here of type [result] and the source here [int.cty]. For this case we are adding the variable [data_pc] as an additional argument. All the functions that use the C function `combine_data_or_status` have automatically this additional argument added. In the stub function the variable [data_pc] is applied to this additional argument *)
1214
let ty =
1315
convert ~c_to_mlc:"combine_data_or_status" ~c:int.cty ~mlc:result
1416
~using:[ data_pc ] ()

0 commit comments

Comments
 (0)