Dart and C : how to ffi and wasm (3) int doube 
Tags: dart, c, ffi, webassembly
Published: 2020-05-17 19:52:37

This document is a continuation of [the previous one](https://dev.to/kyorohiro/dart-and-c-how-to-ffi-and-wasm-2-hello-4jo2).

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

```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;
}
```

### Call from Linux server at dart:ffi

```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
}
``` 

### Call from web browser at dart:js

```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

}
```



### 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