DEV Community

kyorohiro (kiyohiro kawamura)
kyorohiro (kiyohiro kawamura)

Posted on • Updated on

Dart and C : how to ffi and wasm (3) int doube

This document is a continuation of the previous one.

In This document, I introduce to how to use int and double at ffi and wasm.

How to use Int and Double

Create clang function

#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;
}
Enter fullscreen mode Exit fullscreen mode

Call from Linux server at dart:ffi

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
}
Enter fullscreen mode Exit fullscreen mode

Call from web browser at dart:js

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

}
Enter fullscreen mode Exit fullscreen mode

About Uint8List

You can handle the Buffer as Uint8List
In the case of dart:io, buffer.asTypedList(20).
In the case of daer:js, (HEAP8 as typed.Int8List).buffer.asUint8List(buffer, 20)

And, if you change Uint8List, the C language Buffer will also change.

Note!!

Clang's buffer is released by free function.
but, it is not recommended to access released buffer.

Next Time

About Pointer and Buffer

PS

Here's the code for this one
https://github.com/kyorohiro/dart_clang_codeserver/tree/03_buffer_int_double

Top comments (0)