Crates.io | ffishim_derive |
lib.rs | ffishim_derive |
version | 0.1.2 |
source | src |
created_at | 2020-06-30 17:17:24.716364 |
updated_at | 2020-07-01 20:53:35.657134 |
description | Procedural macros for generating ffi-compatible stubs |
homepage | |
repository | https://github.com/mqnfred/ffishim |
max_upload_size | |
id | 259904 |
size | 8,990 |
Many common rust types (like String
for example) cannot be sent over FFI
because their layouts in memory do not match the C ABI (String
does not have
a null byte at its end.) It makes it hard to use native rust types and call
that code from FFI.
This crate provides a shim which will expose FFI-compatible data structures and function wrappers for native rust types and functions.
Here is a quick example of rust code using a native String
and calling that
from C:
#[ffishim_function]
fn hello(s: String) -> String {
format!("Hello, {}!", s)
}
You should be able to call this from C as follows:
#include "ffishim/header.h"
extern result_t *ffi_hello(char *s);
int main() {
char *ffi = malloc(sizeof(char) * 4);
ffi[0] = "f";
ffi[1] = "f";
ffi[2] = "i";
ffi[3] = "\0";
result_t *res = ffi_hello(ffi)
if (res->message != NULL) {
printf("error: %s\n", res->message);
free(res->message);
} else {
printf("%s\n", res->payload);
free(res->payload);
}
free(res);
}
This will print:
Hello, ffi!
Since some type transformations might fail, the functions always return a
result_t
type, which contains a pointer to an error message and a payload. In
case of an error, the payload is nil and the message contains the error string.
You can find more examples of the shim's behavior by looking at the
tests
folder. The structure of the tests is as follow:
src/lib.rs
: the rust library to exposeCargo.toml
: manifest of the rust librarymain.c
: the C code that uses this rust libraryexpected_output
: contains the output expected from running the C programEvery test crate is a stand-alone app leveraging the ffishim library. They will shed light on how to setup the library and use it.
This crate does not currently generate C ABI-compatible bindings. This is because it has been designed to be used together with dustr, which generates Dart bindings on top of this ffi shim.
Because dart ffi support is still in alpha, it cannot quite consume the C ABI just yet. For example, it does not support nested structs, and structures cannot be passed by value to functions.
This crate is still in beta. It is not fit for production use yet.
free_config
if there is a Config
struct in 2 crates. Need name manglingfrom
should become try_from
? (invalid rust string -> CString unsafe)feature(ffishim)
instead of ffi_
prefix::anyhow::Error
explicitlyffishim_derive
documentation on how to use macros