4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Elixir NIFを使ってみる

Posted at

はじめに

NIFを実際に使ってみます
例として、C言語で整数の掛け算を行う関数を作成して、Elixirから使ってみます

C言語ファイルを作成する

multiply.c
#include "erl_nif.h"

static ERL_NIF_TERM multiply(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
    int a, b;
    if (!enif_get_int(env, argv[0], &a) || !enif_get_int(env, argv[1], &b)) {
        return enif_make_badarg(env);
    }
    int result = a * b;
    return enif_make_int(env, result);
}

static ErlNifFunc nif_funcs[] = {
    {"multiply", 2, multiply}
};

ERL_NIF_INIT(Elixir.HelloNif, nif_funcs, NULL, NULL, NULL, NULL)

Elixirモジュールを作成する

hello_nif.ex
defmodule HelloNif do
  @on_load :load_nif

  def load_nif do
    :ok = :erlang.load_nif(~c'./multiply', 0)
  end

  def multiply(_a, _b), do: :erlang.nif_error(:nif_not_loaded)
end

Makefile の作成

Makefile
NIF_NAME = multiply
ERLANG_INCLUDE_DIR = $(shell erl -eval 'io:format("~s", [code:lib_dir(erl_interface, include)])' -s init stop -noshell)
ERTS_INCLUDE_DIR = $(shell erl -eval 'io:format("~s", [code:root_dir() ++ "/erts-" ++ erlang:system_info(version) ++ "/include"])' -s init stop -noshell)

all: compile

compile:
	gcc -o $(NIF_NAME).so -shared -fPIC -I$(ERTS_INCLUDE_DIR) $(NIF_NAME).c

clean:
	rm -f $(NIF_NAME).so

mix に Makefile を組み込む

mix.exs
defmodule HelloNif.MixProject do
  use Mix.Project

  def project do
    [
      app: :hello_nif,
      version: "0.1.0",
      elixir: "~> 1.17",
      compilers: [:elixir_make] ++ Mix.compilers(), # ElixirMake を追加
      deps: deps()
    ]
  end

  # Run "mix help compile.app" to learn about applications.
  def application do
    [
      extra_applications: [:logger]
    ]
  end

  # Run "mix help deps" to learn about dependencies.
  defp deps do
    [
      {:elixir_make, "~> 0.6"}
    ]
  end
end

実行してみる

$ iex -S mix
Erlang/OTP 27 [erts-15.0.1] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]

gcc -o multiply.so -shared -fPIC -I/home/masa/.asdf/installs/erlang/27.0.1/erts-15.0.1/include multiply.c
Compiling 1 file (.ex)
Generated hello_nif app
Interactive Elixir (1.17.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> HelloNif.multiply(2,3)
6
iex(2)> 

コンパイルも実行され、正しい結果が得られました。

試したコード

4
0
2

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
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?