forked from EP-u-NW/web_ffi
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Pulling universal_ffi into a separate repo. Fixing License
- Loading branch information
Showing
259 changed files
with
1,595 additions
and
6,363 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,14 @@ | ||
example/linux/flutter/generated_plugin_registrant.cc eol=lf | ||
example/linux/flutter/generated_plugin_registrant.h eol=lf | ||
example/linux/flutter/generated_plugins.cmake eol=lf | ||
example/macos/Flutter/GeneratedPluginRegistrant.swift eol=lf | ||
example/windows/flutter/generated_plugin_registrant.cc eol=lf | ||
example/windows/flutter/generated_plugin_registrant.h eol=lf | ||
example/windows/flutter/generated_plugins.cmake eol=lf | ||
# Set the default behavior, in case people don't have core.autocrlf set. | ||
* text eol=lf | ||
|
||
# Denote all files that are truly binary and should not be modified. | ||
*.png binary | ||
*.jpg binary | ||
*.pdf binary | ||
*.ico binary | ||
*.wasm binary | ||
*.dll binary | ||
*.so binary | ||
*.dylib binary | ||
*.jar binary | ||
*.zip binary |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
## [2.0.6] | ||
* Pulling universal_ffi into a separate repo. Fixing License | ||
|
||
## [2.0.5] | ||
* Adding topics for pub.dev | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,15 @@ | ||
.PHONY: update-version build run | ||
.PHONY: version build run test | ||
|
||
update-version: | ||
version: | ||
bash ./tools/update-version.sh | ||
|
||
test: | ||
cd wasm_ffi && make test | ||
|
||
build: | ||
cp -f wasm_ffi/example/src/* wasm_ffi/example_flutter/src/ | ||
cp -f wasm_ffi/example/src/* universal_ffi/example/src/ | ||
cp -f wasm_ffi/example/src/* universal_ffi/example_ffi_plugin/src/ | ||
cd wasm_ffi/example && make build | ||
cp -rf wasm_ffi/example/web/assets/* wasm_ffi/example_flutter/assets/ | ||
cp -rf wasm_ffi/example/web/assets/emscripten/* universal_ffi/example/web/assets/ | ||
cp -rf wasm_ffi/example/web/assets/emscripten/* universal_ffi/example_ffi_plugin/assets/ | ||
cp -f example/src/* example_flutter/src/ | ||
cd example && make build | ||
cp -rf example/web/assets/* example_flutter/assets/ | ||
|
||
run-wasm: | ||
cd wasm_ffi/example && make run | ||
run: | ||
cd example && make run | ||
|
||
run-uni-web: | ||
cd universal_ffi/example && make run-wasm | ||
|
||
run-uni-ffi: | ||
cd universal_ffi/example && make run-ffi | ||
test: | ||
dart run build_runner test -- -p chrome |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,60 +1,116 @@ | ||
<div align="center"> | ||
<h1>Dart plugins for native code</h1> | ||
</div> | ||
<div align="center"> | ||
|
||
[![license_badge]][license_url] | ||
[![build_badge]][build_url] | ||
|
||
</div> | ||
|
||
This repo contains Dart plugins to easily incorporate native(C/C++) code into Dart/Flutter projects. | ||
|
||
# wasm_ffi | ||
|
||
[![build_badge]][build_url] | ||
[![github_badge]][wasm_ffi_github_url] | ||
[![wasm_ffi_pub_ver]][wasm_ffi_pub_url] | ||
[![wasm_ffi_pub_points]][wasm_ffi_pub_score_url] | ||
[![wasm_ffi_pub_popularity]][wasm_ffi_pub_score_url] | ||
[![wasm_ffi_pub_likes]][wasm_ffi_pub_score_url] | ||
[![license_badge]][license_url] | ||
|
||
[wasm_ffi][wasm_ffi_github_url] is a `dart:ffi` replacement for the web platform. `dart:ffi` is presently not available for the web. `wasm_ffi` enables using the same native(C/C++) code across all platforms. | ||
|
||
# universal_ffi | ||
|
||
[![github_badge]](https://github.com/vm75/native.ffi/tree/main/universal_ffi) | ||
[![universal_ffi_pub_ver]][universal_ffi_pub_url] | ||
[![universal_ffi_pub_points]][universal_ffi_pub_score_url] | ||
[![universal_ffi_pub_popularity]][universal_ffi_pub_score_url] | ||
[![universal_ffi_pub_likes]][universal_ffi_pub_score_url] | ||
|
||
[universal_ffi](https://github.com/vm75/native.ffi/tree/main/universal_ffi) is a wrapper on top of `wasm_ffi` and `dart:ffi` to provide unified way to use ffi-like bindings for all platforms using the same native code. | ||
It also has some helper methods to make it easier to use. | ||
`wasm_ffi` intends to be a drop-in replacement for `dart:ffi` on the web platform using wasm. wasm_ffi is built on top of [web_ffi](https://pub.dev/packages/web_ffi). | ||
The general idea is to expose an API that is compatible with `dart:ffi` but translates all calls through `dart:js` to a browser running `WebAssembly`. | ||
Wasm with js helper as well as standalone wasm is supported. For testing emcc is used. | ||
|
||
To simplify the usage, [universal_ffi](https://pub.dev/packages/universal_ffi) is provided, which uses `wasm_ffi` on web and `dart:ffi` on other platforms. | ||
|
||
## Differences to dart:ffi | ||
While `wasm_ffi` tries to mimic the `dart:ffi` API as close as possible, there are some differences. The list below documents the most importent ones, make sure to read it. For more insight, take a look at the API documentation. | ||
|
||
* The [`DynamicLibrary`](https://pub.dev/documentation/wasm_ffi/latest/wasm_ffi/DynamicLibrary-class.html) `open` method is asynchronous. It also accepts some additional optional parameters. | ||
* If more than one library is loaded, the memory will continue to refer to the first library. **This breaks calls to later loaded libraries!** One workaround is to specify the correct library.allocator for each usage of `using`. | ||
* Each library has its own memory, so objects cannot be shared between libraries. | ||
* Some advanced types are still unsupported. | ||
* There are some classes and functions that are present in `wasm_ffi` but not in `dart:ffi`; such things are annotated with [`@extra`](https://pub.dev/documentation/wasm_ffi/latest/wasm_ffi_meta/extra-constant.html). | ||
* There is a new class [`Memory`](https://pub.dev/documentation/wasm_ffi/latest/wasm_ffi_modules/Memory-class.html) which is **IMPORTANT** and explained in deepth below. | ||
* If you extend the [`Opaque`](https://pub.dev/documentation/wasm_ffi/latest/wasm_ffi/Opaque-class.html) class, you must register the extended class using [`@extra registerOpaqueType<T>()`](https://pub.dev/documentation/wasm_ffi/latest/wasm_ffi_modules/registerOpaqueType.html) before using it! Also, your class MUST NOT have type arguments (what should not be a problem). | ||
* There are some rules concerning interacting with native functions, as listed below. | ||
|
||
### Rules for functions | ||
There are some rules and things to notice when working with functions: | ||
* When looking up a function using [`DynamicLibrary.lookup<NativeFunction<NF>>()`](https://pub.dev/documentation/wasm_ffi/latest/wasm_ffi/DynamicLibrary/lookup.html) (or [`DynamicLibraryExtension.lookupFunction<T extends Function, F extends Function>()`](https://pub.dev/documentation/wasm_ffi/latest/wasm_ffi/DynamicLibraryExtension/lookupFunction.html)) the actuall type argument `NF` (or `T` respectively) of is not used: There is no type checking, if the function exported from `WebAssembly` has the same signature or amount of parameters, only the name is looked up. | ||
* There are special constraints on the return type (not on parameter types) of functions `DF` (or `F` ) if you call [`NativeFunctionPointer.asFunction<DF>()`](https://pub.dev/documentation/wasm_ffi/latest/wasm_ffi/NativeFunctionPointer/asFunction.html) (or [`DynamicLibraryExtension.lookupFunction<T extends Function, F extends Function>()`](https://pub.dev/documentation/wasm_ffi/latest/wasm_ffi/DynamicLibraryExtension/lookupFunction.html) what uses the former internally): | ||
* You may nest the pointer type up to two times but not more: | ||
* e.g. `Pointer<Int32>` and `Pointer<Pointer<Int32>>` are allowed but `Pointer<Pointer<Pointer<Int32>>>` is not. | ||
* If the return type is `Pointer<NativeFunction>` you MUST use `Pointer<NativeFunction<dynamic>>`, everything else will fail. You can restore the type arguments afterwards yourself using casting. On the other hand, as stated above, type arguments for `NativeFunction`s are just ignored anyway. | ||
* To concretize the things above, [return_types.md](https://github.com/vm75/wasm_ffi/blob/main/wasm_ffi/return_types.md) lists what may be used as return type, everyhing else will cause a runtime error. | ||
* WORKAROUND: If you need something else (e.g. `Pointer<Pointer<Pointer<Double>>>`), use `Pointer<IntPtr>` and cast it yourselfe afterwards using [`Pointer.cast()`](https://pub.dev/documentation/wasm_ffi/latest/wasm_ffi/Pointer/cast.html). | ||
|
||
### Memory | ||
NOTE: While most of this section is still correct, some of it is now automated. | ||
The first call you sould do when you want to use `wasm_ffi` is [`Memory.init()`](https://pub.dev/documentation/wasm_ffi/latest/wasm_ffi_modules/Memory/init.html). It has an optional parameter where you can adjust your pointer size. The argument defaults to 4 to represent 32bit pointers, if you use wasm64, call `Memory.init(8)`. | ||
Contraty to `dart:ffi` where the dart process shares all the memory, on `WebAssembly`, each instance is bound to a `WebAssembly.Memory` object. For now, we assume that every `WebAssembly` module you use has it's own memory. If you think we should change that, open a issue on [GitHub](https://github.com/vm75/wasm_ffi/) and report your usecase. | ||
Every pointer you use is bound to a memory object. This memory object is accessible using the [`@extra Pointer.boundMemory`](https://pub.dev/documentation/wasm_ffi/latest/wasm_ffi/Pointer/boundMemory.html) field. If you want to create a Pointer using the [`Pointer.fromAddress()`](https://pub.dev/documentation/wasm_ffi/latest/wasm_ffi/Pointer/Pointer.fromAddress.html) constructor, you may notice the optional `bindTo` parameter. Since each pointer must be bound to a memory object, you can explicitly speficy a memory object here. To match the `dart:ffi` API, the `bindTo` parameter is optional. Because it is optional, there has to be a fallback mechanism if no `bindTo` is specified: The static [`Memory.global`](https://pub.dev/documentation/wasm_ffi/latest/wasm_ffi_modules/Memory/global.html) field. If that field is also not set, an exception is thrown when invoking the `Pointer.fromAddress()` constructor. | ||
Also, each [`DynamicLibrary`](https://pub.dev/documentation/wasm_ffi/latest/wasm_ffi/DynamicLibrary-class.html) is bound to a memory object, which is again accessible with [`@extra DynamicLibrary.boundMemory`](https://pub.dev/documentation/wasm_ffi/latest/wasm_ffi/DynamicLibrary/boundMemory.html). This might come in handy, since `Memory` implements the [`Allocator`](https://pub.dev/documentation/wasm_ffi/latest/wasm_ffi/Allocator-class.html) class. | ||
|
||
|
||
## Usage | ||
|
||
### Install | ||
``` | ||
dart pub add wasm_ffi | ||
``` | ||
|
||
or | ||
``` | ||
flutter pub add wasm_ffi | ||
``` | ||
|
||
### Usage without ffi bindings | ||
```dart | ||
import 'package:wasm_ffi/ffi.dart' as ffi; | ||
Future<void> main() async { | ||
final library = await DynamicLibrary.open('path to wasm or js'); // NOTE: It is async | ||
final func = library.lookupFunction<int Function(), int Function()>('functionName'); | ||
print(func()); | ||
} | ||
``` | ||
|
||
### Usage with ffi bindings | ||
Generates ffi bindings using [`package:ffigen`](https://pub.dev/packages/ffigen) on the header file. | ||
In the generated bindings file, replace `import 'dart:ffi' as ffi;` with `import 'package:wasm_ffi/ffi.dart' as ffi;` | ||
|
||
``` | ||
import 'package:wasm_ffi/ffi.dart'; | ||
import 'package:wasm_ffi/ffi_utils.dart'; | ||
import 'native_example_bindings.dart'; | ||
... | ||
final library = await DynamicLibrary.open(libName); | ||
final bindings = NativeExampleBindings(library); | ||
// assuming that native library is has a function `hello` which takes a name and returns a string `Hello name!` | ||
using((Arena arena) { | ||
final cString = name.toNativeUtf8(allocator: arena).cast<Char>(); | ||
return bindings.hello(cString).cast<Utf8>().toDartString(); | ||
}, library.allocator); // library.allocator is optional if only one module is loaded | ||
... | ||
``` | ||
|
||
### build wasm | ||
|
||
The generated wasm file needs all exported function. To ensure that, one of the two can be done: | ||
* Use EMSCRIPTEN_KEEPALIVE annotation on all exported functions | ||
* Define EXPORTED_FUNCTIONS when compiling the wasm | ||
|
||
--- | ||
|
||
Contributions are welcome! 🚀 | ||
|
||
[license_badge]: https://img.shields.io/badge/license-MIT-blue.svg | ||
[license_url]: https://github.com/vm75/native.ffi/blob/main/LICENSE | ||
[license_badge]: https://img.shields.io/badge/license-BSD-blue.svg | ||
[license_url]: https://github.com/vm75/wasm_ffi/blob/main/LICENSE | ||
|
||
[build_badge]: https://img.shields.io/github/actions/workflow/status/vm75/native.ffi/.github/workflows/publish.yml?branch=main | ||
[build_url]: https://github.com/vm75/native.ffi/actions | ||
[build_badge]: https://img.shields.io/github/actions/workflow/status/vm75/wasm_ffi/.github/workflows/publish.yml?branch=main | ||
[build_url]: https://github.com/vm75/wasm_ffi/actions | ||
|
||
[github_badge]: https://img.shields.io/badge/github-gray?style=flat&logo=Github | ||
|
||
[wasm_ffi_pub_ver]: https://img.shields.io/pub/v/wasm_ffi | ||
[wasm_ffi_pub_points]: https://img.shields.io/pub/points/wasm_ffi | ||
[wasm_ffi_pub_popularity]: https://img.shields.io/pub/popularity/wasm_ffi | ||
[wasm_ffi_pub_likes]: https://img.shields.io/pub/likes/wasm_ffi | ||
[wasm_ffi_github_url]: https://github.com/vm75/native.ffi/tree/main/wasm_ffi | ||
[wasm_ffi_github_url]: https://github.com/vm75/wasm_ffi | ||
[wasm_ffi_pub_url]: https://pub.dev/packages/wasm_ffi | ||
[wasm_ffi_pub_score_url]: https://pub.dev/packages/wasm_ffi/score | ||
|
||
[universal_ffi_pub_ver]: https://img.shields.io/pub/v/universal_ffi | ||
[universal_ffi_pub_points]: https://img.shields.io/pub/points/universal_ffi | ||
[universal_ffi_pub_popularity]: https://img.shields.io/pub/popularity/universal_ffi | ||
[universal_ffi_pub_likes]: https://img.shields.io/pub/likes/universal_ffi | ||
[universal_ffi_github_url]: https://github.com/vm75/native.ffi/tree/main/universal_ffi | ||
[universal_ffi_pub_url]: https://pub.dev/packages/universal_ffi | ||
[universal_ffi_pub_score_url]: https://pub.dev/packages/universal_ffi/score |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Oops, something went wrong.