Skip to content

Commit

Permalink
Add Using Generated Bindings section
Browse files Browse the repository at this point in the history
  • Loading branch information
kornilova203 committed Jul 5, 2018
1 parent a55e696 commit f9b771b
Show file tree
Hide file tree
Showing 11 changed files with 153 additions and 28 deletions.
7 changes: 4 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,11 @@ lazy val tools = project in file("tools")

lazy val docs = project
.in(file("docs"))
.enablePlugins(ParadoxPlugin)
.enablePlugins(GhpagesPlugin, ParadoxSitePlugin)
.settings(
paradoxTheme := Some(builtinParadoxTheme("generic")),
paradoxProperties in Compile ++= Map(
paradoxProperties in Paradox ++= Map(
"github.base_url" -> "https://github.com/kornilova-l/scala-native-bindgen/tree/master/"
)
),
git.remoteRepo := "[email protected]:kornilova-l/scala-native-bindgen.git"
)
9 changes: 0 additions & 9 deletions docs/src/main/paradox/obtaining-bindgen/index.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ scala-native-bindgen --name uv /usr/include/uv.h -- > uv.scala

## Bindgen Options

| Option | Description |
|----------------------|--------------------------------------------------------------------------------------------------------------|
| `--link` | Library to link with, e.g. `--link` uv for libuv. |
| `--no-link` | Library is static and does not require linking. |
| `--name` | Scala object name that contains bindings. If `--no-link` is specified then `name` should match library name. |
| `--package` | Package name of generated Scala file. |
| `--exclude-prefix` | Functions and unused typedefs will be removed if their names have given prefix. |
| `--extra-arg` | Additional argument to append to the compiler command line. |
| `--extra-arg-before` | Additional argument to prepend to the compiler command line. |
| Option | Description |
|----------------------|---------------------------------------------------------------------------------|
| `--link` | Library to link with, e.g. `--link` uv for libuv. |
| `--no-link` | Library does not require linking. |
| `--name` | Scala object name that contains bindings. Default value set to library name. |
| `--package` | Package name of generated Scala file. |
| `--exclude-prefix` | Functions and unused typedefs will be removed if their names have given prefix. |
| `--extra-arg` | Additional argument to append to the compiler command line. |
| `--extra-arg-before` | Additional argument to prepend to the compiler command line. |
5 changes: 3 additions & 2 deletions docs/src/main/paradox/index.md → docs/src/paradox/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

@@@ index

* [Obtaining bindgen](obtaining-bindgen/index.md)
* [Usage](command-line-usage/index.md)
* [Obtaining Bindgen](obtaining-bindgen/index.md)
* [Command Line Usage](command-line-usage/index.md)
* [Limitations](limitations/index.md)
* [Using Generated Bindings](using-generated-bindings/README.md)

@@@

Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ docker run -v "$(pwd)":/src -v /usr/include:/usr/include \

The docker image does not contain standard headers so it is important to
mount all system include directories that are used by the header file
passed to `scala-native-bindgen`. See the @github[docker-bindgen.sh](/scripts/docker-bindgen.sh) script for
how to wrap the dockerized program. The `$CWD` of the container is
`/src` which should be mounted from `$(pwd)` in case relative paths are
used.
passed to `scala-native-bindgen`.

See the [docker-bindgen.sh] script for how to wrap the dockerized program.
The `$CWD` of the container is `/src` which should be mounted from `$(pwd)`
in case relative paths are used.

Note, the `scalabindgen/scala-native-bindgen:latest` image is updated on
each merge to the `master` branch.

[Docker]: https://www.docker.com/
[docker-bindgen.sh]: https://github.com/kornilova-l/scala-native-bindgen/blob/master/scripts/docker-bindgen.sh

17 changes: 17 additions & 0 deletions docs/src/paradox/obtaining-bindgen/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Obtaining Bindgen

@@@ index

* [Use Docker Container](docker-container.md)
* [Build Binary with CMake](cmake.md)
* [Build Binary with docker-compose](docker-compose.md)

@@@

There are 3 ways to obtain bindgen:

* @ref:[Use docker container](docker-container.md)

* @ref:[Build binary with CMake](cmake.md)

* @ref:[Build binary with docker-compose](docker-compose.md)
112 changes: 112 additions & 0 deletions docs/src/paradox/using-generated-bindings/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Using Generated Bindings

Consider following header file:

```c
struct point {
float x;
float y;
};

struct vector {
struct point a;
struct point b;
};

struct vector *add(struct vector *v1, struct vector *v2);
```
Bindgen will generate type aliases for the structs, binding for function `add`
and helper functions that make usage of structs easier.
```scala
import scala.scalanative._
import scala.scalanative.native._
@native.link("mylib")
@native.extern
object mylib {
type struct_point = native.CStruct2[native.CFloat, native.CFloat]
type struct_vector = native.CStruct2[struct_point, struct_point]
def add(v1: native.Ptr[struct_vector], v2: native.Ptr[struct_vector]): native.Ptr[struct_vector] = native.extern
}
import mylib._
object mylibHelpers {
implicit class struct_point_ops(val p: native.Ptr[struct_point]) extends AnyVal {
def x: native.CFloat = !p._1
def x_=(value: native.CFloat): Unit = !p._1 = value
def y: native.CFloat = !p._2
def y_=(value: native.CFloat): Unit = !p._2 = value
}
def struct_point()(implicit z: native.Zone): native.Ptr[struct_point] = native.alloc[struct_point]
implicit class struct_vector_ops(val p: native.Ptr[struct_vector]) extends AnyVal {
def a: native.Ptr[struct_point] = p._1
def a_=(value: native.Ptr[struct_point]): Unit = !p._1 = !value
def b: native.Ptr[struct_point] = p._2
def b_=(value: native.Ptr[struct_point]): Unit = !p._2 = !value
}
def struct_vector()(implicit z: native.Zone): native.Ptr[struct_vector] = native.alloc[struct_vector]
}
```
Let's write code that creates two vectors, adds them and prints resulting
vector.

First we need to create points for vectors. We will use `native.Zone` to
allocate struct (more information on memory management can be found
here: [Scala Native memory management]).

Helper object `mylibHelpers` contains function for struct allocation.
To import it use `import mylibHelpers._`

Let's create points for first vector:
```scala
import mylibHelpers._
import scala.scalanative.native.Zone

object Hello extends App {
Zone { implicit zone =>
val vec1p1 = struct_point()
val vec1p2 = struct_point()
}
}
```

Now we want to set fields of created points. Scala Native provides access
to fields by using `_N` methods where `N` is index of a field
(see [Scala Native memory layout types]).

Bindgen generates implicit helper classes that wrap calls to `_N` in functions
with meaningful names. We already imported helper class, so we can use the
functions:
```scala
vec1p1.x = 0
vec1p1.y = 1

vec1p2.x = 6
vec1p2.y = 3
```

Lets create first vector. Note that `struct_vector` contains
fields of type `struct_point` but setters accept variables of type
`native.Ptr[struct_point]`. It helps to avoid Scala Native limitation that
does not allow passing structs and arrays by value
(see @github[scala-native/scala-native#555](scala-native/scala-native#555)).
```scala
val vec1 = struct_vector()
vec1.a = vec1p1
vec1.b = vec1p2
```
Repeat these steps to create second vector. Once both vectors are created we can
call `add` function and print the result:
```scala
val vec3 = mylib.add(vec1, vec2)
println(s"(${vec3.a.x}, ${vec3.a.y}), (${vec3.b.x}, ${vec3.b.y})")
```

[Scala Native memory management]: http://www.scala-native.org/en/latest/user/interop.html#memory-management
[Scala Native memory layout types]: http://www.scala-native.org/en/latest/user/interop.html#memory-layout-types
3 changes: 2 additions & 1 deletion project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.3.7")
addSbtPlugin("com.lightbend.paradox" % "sbt-paradox" % "0.3.5")
addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "1.3.2")
addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.6.2")

0 comments on commit f9b771b

Please sign in to comment.