Dart とC言語の連携 : dart:js と dart:ffi の両立 (1)

本文では、Dart で C言語 とを連携させる方法について解説していきます。

また、サーバーサイドや、Android や iOS や WindowsやLinuxとの連携するだけでなく、同時に、Web クライアントとも連携する方法をについても解説して行きます。

これらを同時に連携できるノウハウを知る事によって、私たちは、C言語やGo言語やRustで書かれた機能を、プラットフォームを超えて簡単に自プロジェクトに取り込む事ができるようになります。

(1) [開発環境](https://qiita.com/kyorohiro/items/fdb948886923da5d4d75)
(2) [Hello World](https://qiita.com/kyorohiro/items/cffecf482ed784b6f1b0)
(3) [Int Double](https://qiita.com/kyorohiro/items/c99ed94bfadd2fafbf6d)
(4) [Pointer Buffer](https://qiita.com/kyorohiro/items/fb4754a1a7e62cc62e45)
(5) [構造体 Object](https://qiita.com/kyorohiro/items/77fd6a276c3c7d69cb74)

## Dart と  Native との連携　は dart:ffiで

dart:ffi を 用いて、 システム言語で書かれたコードと連携する事ができます。

複数のプログラムやアプリで共通で使用する、関数や定数が格納されている、shared libirary と言うものがありまして、Dartはdart:ffi を利用して、この shared library を利用する事ができます。

https://dart.dev/guides/libraries/c-interop


なので、C言語で書かれたコードをshared libirary に変換してあげて、これをDartから読み込んでいくと言う流れになります。


## Dart と WebAssembly との　連携 は dart:jsで

dart:js と WebAssembly を用いて、システム言語で書かれたコードを、Webブラウザーで利用する事が出来ます。

https://developer.mozilla.org/en-US/docs/WebAssembly

システム言語で書かれたコードを WebAssembly 化してあげてから、そのコードをdart:jsを経由して利用すると言う流れになります。


## DartでC言語を利用するメリット

まず、高速で動作します。そして、システム言語で書かれている様々な機能を自プロジェクトに取り込むこむ事ができるようになります。

Dartだと遅くで良いコードが出来たけど実用性がないなぁなど、お悩みでしたら、
それを解決する手段になるかも知れません。


# 環境を構築
まずは、サーバーサイドとブラウザー向けの環境について解説して行きます。
で、この開発環境を合わせるために、DockerとCode-Server を利用します。
参考までに、

```Dockerfile
FROM ubuntu:20.04
ENV DEBIAN_FRONTEND noninteractive

# install vscode (code-server)
WORKDIR /works
COPY ./build_resource/code-server-3.0.0-linux-x86_64.tar.gz /works/code-server-3.0.0-linux-x86_64.tar.gz
RUN tar -xzf code-server-3.0.0-linux-x86_64.tar.gz -C ./ --strip-components 1
RUN /works/code-server --install-extension ms-vscode.cpptools

# install C
WORKDIR /works
RUN apt-get update
RUN apt-get install -y wget gnupg1
RUN apt-get install musl-dev -y
RUN apt-get install build-essential -y
RUN apt-get install cmake -y 
RUN apt-get install python3 -y
RUN apt-get install python3-pip -y
RUN ln -s `which pip3` /usr/bin/pip 
RUN ln -s `which python3` /usr/bin/python 

# install WebAssembly
WORKDIR /works/wasm
RUN apt-get install -y git
RUN git clone https://github.com/emscripten-core/emsdk.git

WORKDIR /works/wasm/emsdk
RUN ./emsdk install latest
RUN ./emsdk activate latest
#RUN source /works/wasm/emsdk/emsdk_env.sh --build=Release
ENV PATH=${PATH}:/works/wasm/emsdk:/works/wasm/emsdk/node/12.9.1_64bit/bin:/works/wasm/emsdk/upstream/emscripten
RUN apt install -y nodejs npm


# install Dart
RUN apt-get update
RUN apt-get install -y wget gnupg1
RUN apt-get install apt-transport-https
RUN sh -c 'wget -qO- https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -'
RUN sh -c 'wget -qO- https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > /etc/apt/sources.list.d/dart_stable.list'
RUN apt-get update
RUN apt-get -y install dart
RUN /works/code-server --install-extension Dart-Code.dart-code

ENV PATH=${PATH}:/lib/dart/bin
ENV PATH="${PATH}:/root/.pub-cache/bin"


CMD ["/works/code-server", "--auth","none", "--host","0.0.0.0","--port","8443", "/app"]


```

具体的には、以下のような構成にしました。
https://github.com/kyorohiro/dart_clang_codeserver/tree/01_env

```
$ docker-compose build 
$ docker-compose up -d
```

とした後で、ブラウザーで `http://127.0.0.1:8443` にアクセスすると、VSCodeが開きます。
※ 127.0.0.1は環境依存

'emcc' 'gcc' 'dart' が利用できるはずです


# 次回
実際に、コード書きながら、dart:ffi、dart:js を 用いてC言語と連携して行きます。


# PS

mbedtls_dart と言う Package の開発を始めました。この文は、ここで得たノウハウになります。
https://github.com/kyorohiro/mbedtls_dart

以下でも書いてます
https://dev.to/kyorohiro/dart-and-c-how-to-support-ffi-and-wasm-1-514f