Skip to content

Create C bindings #688

@Johannesd3

Description

@Johannesd3

@d4rwel inspired me to write down some thoughts I had about creating C bindings for librespot. There's no need to change anything in librespot itself, it could happen in its own crate/repo. However, I assume that #665 is ready, but this could be accomplished with git dependencies.

So here's a rough plan:

Create a rust library crate and add the following to the Cargo.toml:

[dependencies]
librespot = "choose version"
tokio = "choose version"

[lib]
crate-type = ["cdylib"]

Pick some important Rust functions from librespot. Maybe look at the examples to decide what's needed.

Create functions that are callable from C as shown in this example.

Important: Wrap everything into a catch_unwind. If an error occurs, there might be UB if it reaches the border to C.

There are certainly some structs that need to be passed. Since those structs are not compatible with C, they must be passed as opaque type behind a pointer (as in the example).

Some functions are async. These functions must be executed by a tokio runtime. Create functions to created and destroy a tokio runtime. Return this runtime as opaque struct. (This struct could even be called librespot if the user shouldn't be bothered with implementation details.) For every function call that executes an async rust function, a pointer to this struct must be passed.

Remember, destructors in Rust are implicit. It's important to create functions that deallocate resources again, although these functions seem to do nothing. Look at the example above.

If it's ready, running cargo build will produce a .so file in target/debug.

Run cargo install cbindgen to install a tool to create a C header file. cbindgen --lang c will hopefully spit out the expected result.

You can now write a C application that uses librespot. Just include the header and link it against this .so file.

How does it sound?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions