前回の続きです。
int や double や pointer を使ってみましょう
Int と Double を 使ってみる
C言語の関数を作成する。
ky.c
# include <stdio.h>
# include <stdlib.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="['_sum_int','_sum_double']"
// cp libky.js ../web/libky.js
// cp libky.wasm ../web/libky.wasm
int sum_int(int a, int b){
return a + b;
}
double sum_double(double a, double b) {
return a + b;
}
Dartから 関数を呼び出す:Linux Server
main.dart
import 'dart:ffi' as ffi;
import 'dart:typed_data' as typed;
// dart ./bin/main.dart
ffi.DynamicLibrary dylib = ffi.DynamicLibrary.open('/app/libc/libky.so');
// int sum_int(a,b)
typedef SumIntFunc = ffi.Int32 Function(ffi.Int32 a, ffi.Int32 b);
typedef SumInt = int Function(int a, int b);
SumInt _sum_int = dylib
.lookup<ffi.NativeFunction<SumIntFunc>>('sum_int')
.asFunction<SumInt>();
int sumInt(int a, int b) {
return _sum_int(a, b);
}
// int sum_double(a,b)
typedef SumDoubleFunc = ffi.Double Function(ffi.Double a, ffi.Double b);
typedef SumDouble = double Function(double a, double b);
SumDouble _sum_double = dylib
.lookup<ffi.NativeFunction<SumDoubleFunc>>('sum_double')
.asFunction<SumDouble>();
double sumDouble(double a, double b) {
return _sum_double(a, b);
}
void main(List<String> args) {
// int
print('${sumInt(10, 100)}'); // 110
// double
print('${sumDouble(10.1, 100.2)}'); // 110.3
// pointer and buffer
}
Dartから 関数を呼び出す:Webブラウザー
main.dart
import 'dart:js' as js;
import 'dart:typed_data' as typed;
// webdev serve --hostname=0.0.0.0
js.JsObject Module = js.context['Module'];
js.JsFunction _sum_int = Module.callMethod('cwrap',['sum_int','number',['number', 'number']]);
int sumInt(int a, int b) {
return _sum_int.apply([a, b]);
}
js.JsFunction _sum_double = Module.callMethod('cwrap',['sum_double','number',['number', 'number']]);
double sumDouble(double a, double b) {
return _sum_double.apply([a, b]);
}
js.JsFunction _to_uint8list= js.context['to_uint8list'];// from util.js
typed.Uint8List toUint8List(int buffer, int length) {
return _to_uint8list.apply([buffer, length]);
}
void main() {
// int
print('${sumInt(10, 100)}'); // 110
// double
print('${sumDouble(10.1, 100.2)}'); // 110.3
}
次回
Pointer と Buffer を扱ってみます。
PS
今回のコードは以下です
https://github.com/kyorohiro/dart_clang_codeserver/tree/03_buffer_int_double
以下でも書いています
https://dev.to/kyorohiro/dart-and-c-how-to-ffi-and-wasm-3-int-doube-buffer-pointer-832