Skip to content

Commit 4b310ea

Browse files
committed
Add Using Generated Bindings section
1 parent 8693520 commit 4b310ea

File tree

3 files changed

+128
-14
lines changed

3 files changed

+128
-14
lines changed

docs/SUMMARY.md

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# Summary
22

3-
* [Obtaining bindgen](obtaining-bindgen/README.md)
4-
* [Use docker container](obtaining-bindgen/docker-container.md)
5-
* [Build binary with CMake](obtaining-bindgen/cmake.md)
6-
* [Build binary with docker-compose](obtaining-bindgen/docker-compose.md)
7-
* [Usage](command-line-usage/README.md)
3+
* [Obtaining Bindgen](obtaining-bindgen/README.md)
4+
* [Use Docker Container](obtaining-bindgen/docker-container.md)
5+
* [Build Binary with CMake](obtaining-bindgen/cmake.md)
6+
* [Build Binary with docker-compose](obtaining-bindgen/docker-compose.md)
7+
* [Command Line Usage](command-line-usage/README.md)
88
* [Limitations](limitations/README.md)
9+
* [Using Generated Bindings](using-generated-bindings/README.md)
910

docs/command-line-usage/README.md

+9-9
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ scala-native-bindgen --name uv /usr/include/uv.h -- > uv.scala
1414

1515
## Bindgen Options
1616

17-
| Option | Description |
18-
|----------------------|--------------------------------------------------------------------------------------------------------------|
19-
| `--link` | Library to link with, e.g. `--link` uv for libuv. |
20-
| `--no-link` | Library is static and does not require linking. |
21-
| `--name` | Scala object name that contains bindings. If `--no-link` is specified then `name` should match library name. |
22-
| `--package` | Package name of generated Scala file. |
23-
| `--exclude-prefix` | Functions and unused typedefs will be removed if their names have given prefix. |
24-
| `--extra-arg` | Additional argument to append to the compiler command line. |
25-
| `--extra-arg-before` | Additional argument to prepend to the compiler command line. |
17+
| Option | Description |
18+
|----------------------|---------------------------------------------------------------------------------|
19+
| `--link` | Library to link with, e.g. `--link` uv for libuv. |
20+
| `--no-link` | Library does not require linking. |
21+
| `--name` | Scala object name that contains bindings. Default value set to library name. |
22+
| `--package` | Package name of generated Scala file. |
23+
| `--exclude-prefix` | Functions and unused typedefs will be removed if their names have given prefix. |
24+
| `--extra-arg` | Additional argument to append to the compiler command line. |
25+
| `--extra-arg-before` | Additional argument to prepend to the compiler command line. |
+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Using Generated Bindings
2+
3+
Consider following header file:
4+
5+
```c
6+
struct point {
7+
float x;
8+
float y;
9+
};
10+
11+
struct vector {
12+
struct point a;
13+
struct point b;
14+
};
15+
16+
struct vector *add(struct vector *v1, struct vector *v2);
17+
```
18+
19+
Bindgen will output following bindings for the header file:
20+
```scala
21+
import scala.scalanative._
22+
import scala.scalanative.native._
23+
24+
@native.link("mylib")
25+
@native.extern
26+
object mylib {
27+
type struct_point = native.CStruct2[native.CFloat, native.CFloat]
28+
type struct_vector = native.CStruct2[struct_point, struct_point]
29+
def add(v1: native.Ptr[struct_vector], v2: native.Ptr[struct_vector]): native.Ptr[struct_vector] = native.extern
30+
}
31+
32+
import mylib._
33+
34+
object mylibHelpers {
35+
36+
implicit class struct_point_ops(val p: native.Ptr[struct_point]) extends AnyVal {
37+
def x: native.CFloat = !p._1
38+
def x_=(value: native.CFloat): Unit = !p._1 = value
39+
def y: native.CFloat = !p._2
40+
def y_=(value: native.CFloat): Unit = !p._2 = value
41+
}
42+
43+
def struct_point()(implicit z: native.Zone): native.Ptr[struct_point] = native.alloc[struct_point]
44+
45+
implicit class struct_vector_ops(val p: native.Ptr[struct_vector]) extends AnyVal {
46+
def a: native.Ptr[struct_point] = p._1
47+
def a_=(value: native.Ptr[struct_point]): Unit = !p._1 = !value
48+
def b: native.Ptr[struct_point] = p._2
49+
def b_=(value: native.Ptr[struct_point]): Unit = !p._2 = !value
50+
}
51+
52+
def struct_vector()(implicit z: native.Zone): native.Ptr[struct_vector] = native.alloc[struct_vector]
53+
}
54+
```
55+
It generated alias type for the structs, binding for function `add` and
56+
helper functions that make usage of structs easier.
57+
58+
Let's write code that creates two vectors, adds them and prints resulting
59+
vector.
60+
61+
First we need to create points for vectors. We will use `native.Zone` to
62+
allocate struct (more information on memory management can be found
63+
here: [Scala Native memory management]).
64+
65+
Helper object `mylibHelpers` contains function for struct allocation.
66+
To import it use `import mylibHelpers._`
67+
68+
Lets create points for first vector:
69+
```scala
70+
import mylibHelpers._
71+
import scala.scalanative.native.Zone
72+
73+
object Hello extends App {
74+
Zone { implicit zone =>
75+
val vec1p1 = struct_point()
76+
val vec1p2 = struct_point()
77+
}
78+
}
79+
```
80+
81+
Now we want to set fields of created points. Scala Native provides access
82+
to fields by using `_N` methods where `N` is index of a field
83+
(see [Scala Native memory layout types]).
84+
85+
Bindgen generates implicit helper class that wraps calls to `_N` in functions
86+
with meaningful names. We already imported helper class, so we can use it:
87+
```scala
88+
vec1p1.x = 0
89+
vec1p1.y = 1
90+
91+
vec1p2.x = 6
92+
vec1p2.y = 3
93+
```
94+
95+
Lets create first vector. Note that `struct_vector` contains
96+
fields of type `struct_point` but setters accept variables of type
97+
`native.Ptr[struct_point]` because Scala Native does not allow passing
98+
structs and arrays by value (see [scala-native/scala-native#555]).
99+
```scala
100+
val vec1 = struct_vector()
101+
vec1.a = vec1p1
102+
vec1.b = vec1p2
103+
```
104+
Repeat these steps to create second vector. Once both vectors are created we can
105+
call `add` function and print the result:
106+
```scala
107+
val vec3 = mylib.add(vec1, vec2)
108+
println(s"(${vec3.a.x}, ${vec3.a.y}), (${vec3.b.x}, ${vec3.b.y})")
109+
```
110+
111+
[Scala Native memory management]: http://www.scala-native.org/en/latest/user/interop.html#memory-management
112+
[Scala Native memory layout types]: http://www.scala-native.org/en/latest/user/interop.html#memory-layout-types
113+
[scala-native/scala-native#555]: https://github.com/scala-native/scala-native/issues/555

0 commit comments

Comments
 (0)