8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Code-Server x Dart with ffi x Go x Clang

Last updated at Posted at 2019-12-22

Dart Advent Calendar 2019 の 記事です。

Dart の Native Interface に ついての記事です。
Go や C言語の機能をDartで利用する方法について解説します。また、すぐに Native Interface を試せるように、 Docker Image を 用意しました。

Native Interface とは : C言語 の ライブラリーを使用することができる機能です

C言語 の ライブラリーを使用することができる機能です。ただし、C言語と言ってもC言語でのライブラリーに閉じたものではないです。

Go言語 や Rust言語などのシステム言語は、Shared Libraryを作成することができます。

この Shared Library 経由すれば、Dartで GoやRustなどの機能も利用できます。

とても便利 : OSの機能をフルに使える

Dartは、まだまだライブラリーが不足している状態です。ですので、C言語で開発されたライブラリーや、Goで開発されたライブラリーを利用する必要があります。
Native Interface によち、 Dart がより便利になります。

開発環境 : Docker 環境を用意しました。

Code-Server という VSCode が オンライン上で動作する エディターを含めました。
このため、 Dockerを起動すれば、即、開発ができます。

FROM ubuntu:20.04

WORKDIR /works
# 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

# install go
RUN apt-get install software-properties-common -y
#RUN add-apt-repository ppa:longsleep/golang-backports
RUN apt-get update
RUN apt-get install golang-go -y
RUN apt-get install git -y
RUN go get github.com/ramya-rao-a/go-outline
RUN go get github.com/mdempsky/gocode
RUN go get github.com/uudashr/gopkgs/cmd/gopkgs
RUN go get github.com/sqs/goreturns
RUN go get github.com/rogpeppe/godef

# install c
RUN apt-get install musl-dev -y

# code-server
RUN wget https://github.com/cdr/code-server/releases/download/2.1692-vsc1.39.2/code-server2.1692-vsc1.39.2-linux-x86_64.tar.gz
RUN tar -xzf code-server2.1692-vsc1.39.2-linux-x86_64.tar.gz -C ./ --strip-components 1


RUN /works/code-server --install-extension Dart-Code.dart-code
RUN /works/code-server --install-extension ms-vscode.go
RUN /works/code-server --install-extension ms-vscode.cpptools

WORKDIR /app
ENV PATH=${PATH}:/lib/dart/bin
ENV PATH="${PATH}:/root/.pub-cache/bin"
RUN pub global activate webdev
RUN pub global activate stagehand

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

docker-compose.yml
version: '3'
services: 
  app:
    build: ./app
    ports:
     - "8080:8080"
     - "8443:8443"
    volumes: 
      - ./app:/app
    # - /var/run/docker.sock:/var/run/docker.sock
    command: /works/code-server --auth none --host 0.0.0.0 --port 8443 /app 

具体的には、github を参照してください。

開発環境を起動する。

$ git clone https://github.com/kyorohiro/advent-2019-code-server.git
$ cd advent-2019-code-server/extra/dart_fmi_and_go_and_c
$ docker-compose build
$ docker-compose up -d

ブラウザーで、http://127.0.0.1:8443/ を開く

Screen Shot 2019-12-22 at 20.31.13.png

Go で Shared Library を 作成する。

VSCode->File(Menu)->/app/wgo に移動する。

hello.go
package main

import "C"
import "fmt"

//export PrintHello
func PrintHello() {
	fmt.Print("Hello,World")
}

func main() {}

Goの PrintHello 関数を、Dart から呼ばれる予定です。

$ go build -o libhello.so  -buildmode=c-shared  hello.go

とすると、libhello.hlibhello.so というファイルができます。
Dart で読み込む前に、C言語から読み込んでみましょう。

main_hello.c
#include <stdio.h>
#include "libhello.h"


int main(int argc, char const *argv[])
{
  PrintHello();
  return 0;
}

Terminal

$ gcc -Wall -o main_hello.exe main_hello.c -L. -lhello
$ LD_LIBRARY_PATH=. ./main_hello.exe -L. -lhello
Hello,World

おっ!! 上手く動作しました。

Dart から読み込んでみる。

VSCode->File(Menu)->/app/wdart に移動する。

bin/main.dart
import 'dart:ffi' as ffi;

typedef PrintHello_func = ffi.Void Function();
typedef PrintHello = void Function();

void main(List<String> arguments) {
  var path = "/app/wgo/libhello.so";
  ffi.DynamicLibrary dylib = ffi.DynamicLibrary.open(path);
  final PrintHello hello = dylib
      .lookup<ffi.NativeFunction<PrintHello_func>>('PrintHello')
      .asFunction();
  hello();
}


Terminal
$ dart ./bin/main.dart
Hello,World

PS

C言語の環境も用意しました。
先ほどの、github レポジトリーから見れます。


Go言語で開発された機能をDartでフルに利用できます。ので、Dart から ほぼなんでも出来る状態になりました。
FMIがサポートされたことで、気軽に Native Interface を書けるようになったと思います。


サーバーサイド向けでしたら、開発には、Docker Image などが便利だと思います。

今回、使用した Code-Server について、下記 Advent にて
20回以上に分けて解説していますので、興味ある方は、ご参照ください。

※ Docker Image として固めてHub に 配置するなどすれば、必ず動作するようになりますが、Image には固めていません。個人利用する際は、 Image に固めて保管しておくことをお勧めします。

Code

8
4
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?