はじめに
Zigは、堅牢、最適、および再利用可能なソフトウェアをメンテナンスするための汎用プログラミング言語およびツールチェインです
引用元
Zigler を使うことで、 Elixir から Zig のコードを呼び出すことができます
本記事では Livebook で Zigler を使い、 Zig のコードを実行します
実装したコードはこちら
前提条件
実行環境には Zig をインストールしておきます
セットアップ
セットアップセルで Zigler をインストールします
Mix.install([
{:zigler, "~> 0.13.3"}
])
Zig モジュールの定義
Zig 実行用のモジュールを定義します
defmodule ExampleZig do
use Zig, otp_app: :zigler
~Z"""
const std = @import("std");
const beam = @import("beam");
pub fn add(a: i32, b: i32) i32 {
return a + b;
}
pub fn multiply(a: i32, b: i32) i32 {
return a * b;
}
pub fn sort(slice: []i32) []i32 {
std.mem.sort(i32, slice, {}, comptime std.sort.asc(i32));
return slice;
}
pub fn hello(name: []const u8) ![]u8 {
const greeting = "Hello, ";
const total_len = greeting.len + name.len;
var buffer = try beam.allocator.alloc(u8, total_len);
@memcpy(buffer[0..greeting.len], greeting);
@memcpy(buffer[greeting.len..], name);
return buffer;
}
"""
end
~Z
のシギル 内に Zig のコードを書きます
メモリ割り当てには beam.allocator
を利用します
コードを実行すると、以下のような標準出力が表示されます
01:57:49.573 [info] searching for zig in /home/livebook/.cache/zigler/zig-linux-aarch64-0.13.0/zig
01:57:49.573 [info] system zig found in /usr/local/zig-linux/zig
01:57:49.573 [debug] running command: /usr/local/zig-linux/zig fmt /tmp/Elixir.ExampleZig/build.zig
01:57:49.583 [debug] wrote build.zig to /tmp/Elixir.ExampleZig/build.zig
01:57:49.600 [info] searching for zig in /home/livebook/.cache/zigler/zig-linux-aarch64-0.13.0/zig
01:57:49.601 [info] system zig found in /usr/local/zig-linux/zig
01:57:49.601 [debug] running command: /usr/local/zig-linux/zig run -lc --dep analyte -Mmain=/home/livebook/.cache/mix/installs/elixir-1.17.2-erts-15.0/7151676201b96057dc15ed4fdc619273/_build/dev/lib/zigler/priv/beam/sema.zig -Merl_nif=/home/livebook/.cache/mix/installs/elixir-1.17.2-erts-15.0/7151676201b96057dc15ed4fdc619273/_build/dev/lib/zigler/priv/beam/stub_erl_nif.zig --dep erl_nif -Mbeam=/home/livebook/.cache/mix/installs/elixir-1.17.2-erts-15.0/7151676201b96057dc15ed4fdc619273/_build/dev/lib/zigler/priv/beam/beam.zig -Mattributes=/tmp/Elixir.ExampleZig/attributes.zig --dep erl_nif --dep beam --dep attributes -Manalyte=/home/livebook/.local/share/livebook/autosaved/2024_12_27/01_36_j6eb/.Elixir.ExampleZig.zig
01:57:50.389 [info] searching for zig in /home/livebook/.cache/zigler/zig-linux-aarch64-0.13.0/zig
01:57:50.389 [info] system zig found in /usr/local/zig-linux/zig
01:57:50.389 [debug] running command: /usr/local/zig-linux/zig fmt /tmp/Elixir.ExampleZig/module.zig
01:57:50.394 [debug] wrote module code to /tmp/Elixir.ExampleZig/module.zig
01:57:50.395 [info] searching for zig in /home/livebook/.cache/zigler/zig-linux-aarch64-0.13.0/zig
01:57:50.395 [info] system zig found in /usr/local/zig-linux/zig
01:57:50.395 [debug] running command: /usr/local/zig-linux/zig build -Doptimize=Debug --prefix /home/livebook/.cache/mix/installs/elixir-1.17.2-erts-15.0/7151676201b96057dc15ed4fdc619273/_build/dev/lib/zigler/priv
01:57:51.511 [debug] built library at /home/livebook/.cache/mix/installs/elixir-1.17.2-erts-15.0/7151676201b96057dc15ed4fdc619273/_build/dev/lib/zigler/priv/lib/Elixir.ExampleZig.so
01:57:51.549 [debug] loaded module at Elixir.ExampleZig
Zシギル内に定義したコードを元として NIF が生成、ビルドされ、 NIF のロードまで実行されています
定義したモジュールは普通の Elixir モジュールと同じように呼び出すことができます
ExampleZig.add(3, 4)
実行結果
7
ExampleZig.multiply(3, 4)
実行結果
12
ExampleZig.sort([8, 5, 6, 2])
実行結果
[2, 5, 6, 8]
ExampleZig.hello("Zig")
実行結果
"Hello, Zig"
まとめ
NIF を作るときのややこしい部分を Zigler が全てやってくれるので、簡単に Elixir から Zig のコードを実行できました