前回作成した環境で、Shared Library と JS を作成してみます。
"Hello!!" と表示する C言語の関数を作成して、"Webブラウザー" と "Linux Server " でその関数を呼び出してみます。
C言語の関数を作成する。
:ky.c
# include <stdio.h>
// [Linux]
// find . -name "*.o" | xargs rm
// gcc -Wall -Werror -fpic -I. -c ky.c -o ky.o
// gcc -shared -o libky.so ky.o
// [Wasm]
// find . -name "*.o" | xargs rm
// find . -name "*.wasm" | xargs rm
// emcc ky.c -o ky.o
// emcc ky.o -o libky.js -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' -s EXPORTED_FUNCTIONS="['_print_hello']"
// cp libky.js ../web/libky.js
// cp libky.wasm ../web/libky.wasm
void print_hello() {
printf("Hello!!\n");
}
Shared Library を作成する
$ find . -name "*.o" | xargs rm
$ gcc -Wall -Werror -fpic -I. -c ky.c -o ky.o
$ gcc -shared -o libky.so ky.o
libky.so というファイルが出来ます。
JSとWASMを作成する
$ find . -name "*.o" | xargs rm
$ find . -name "*.wasm" | xargs rm
$ emcc ky.c -o ky.o
$ emcc ky.o -o libky.js -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' -s EXPORTED_FUNCTIONS="['_print_hello']"
Dartから 関数を呼び出す:Linux Server
main.dart
import 'dart:ffi' as ffi;
typedef PrintHelloFunc = ffi.Pointer<ffi.Void> Function();
typedef PrintHello = ffi.Pointer<ffi.Void> Function();
ffi.DynamicLibrary dylib = ffi.DynamicLibrary.open('/app/libc/libky.so');
PrintHello _print_hello = dylib
.lookup<ffi.NativeFunction<PrintHelloFunc>>('print_hello')
.asFunction();
void printHello() {
_print_hello();
}
main(List<String> args) {
printHello();
}
Dartから 関数を呼び出す:Webブラウザー
main.dart
import 'dart:js' as js;
js.JsObject Module = js.context['Module'];
js.JsFunction _print_hello = Module.callMethod('cwrap',['print_hello','',[]]);
void printHello() {
_print_hello.apply([]);
}
void main() {
printHello();
}
試してみる
dart ./bin/main.dart
webdev serve --hostname=0.0.0.0
以上
次回
Buffer の扱いかた または、各種Primitive の扱いについて解説します。
PS
今回のコードは以下です
https://github.com/kyorohiro/dart_clang_codeserver/tree/02_hello
以下でも書いています
https://dev.to/kyorohiro/dart-and-c-how-to-ffi-and-wasm-2-hello-4jo2