Scilab > C言語プログラムの利用
広告
基本的な手順
基本的な手順は以下です。- C言語で関数を実装
- ilib_for_linkコマンドを使い、ビルド
- execコマンドで関数をロード
- callコマンドで関数を実行
サンプルコード
例として、1つ目の引数をインクリメントするだけの関数を使います。#include <stdio.h> void test_inc(int *a, int *result) { result[0] = a[0] + 1; }
returnではなく、2つ目の引数に結果を格納している点が特徴です。 計算結果をscilabに返すためには、計算結果を格納するための変数を、引数として定義する必要があります。
上記プログラムをtest.cというファイルに保存します。
ビルド
C言語ファイルをビルドするために、scilabのilib_for_linkコマンドを使います。 以下のサンプルです。-->ilib_for_link('test_inc','test.c',[],"c");
- 1つ目の引数は、実行したい関数名です。
- 2つ目の引数は、プログラムファイル名です。
- 3つ目の引数は、ビルドに必要な共有ライブラリ名です。今回は不要です。
- 4つ目の引数は、言語です。C言語の場合は"c"です。
ビルドに成功すると、loader.sceファイルが生成されます。
ロード
ビルドに成功すると、loader.sceファイルが生成されるはずです。 このファイルを実行すると、ビルドした関数がロードされ、scilabから実行できるようになります。-->exec loader.sceこれでokです。
C関数の実行
callコマンドを使い、C関数を実行します。 以下が、test_incを呼び出す例です。この結果、101が返されます。
call("test_inc", 100, 1, "i", "out", [1,1], 2, "i")
callコマンドの引数は複雑です。
まず最初に、実行したい関数名を指定します。
次に、関数に渡す引数を指定します。「関数に渡す引数」は、3つの引数(上記例だと100, 1, "i")で指定します。
- 値
- 引数の順番(1はじまり)
- 引数の型(intはi, doubleはd、floatはr、文字列はc)
「関数に渡す引数」が複数の場合は、上記3つ組を、連続で指定します。
「関数に渡す引数」を指定したら、次に"out"を指定します。 これは、「この後に返り値の情報を指定しますよ」というおまじないです。
返り値は、以下の3つ引数で指定します。
- 返り値の行列の形。単純な値であれば[1,1]です。
- 返り値の順番(引数の順番に続く番号)
- 返り値の型
Ubuntuの場合
Ubuntu 14.04で試したとき、apt-getでインストールしたscilabだと、ilib_for_linkコマンド実行時にエラーが発生しました。バイナリ版(version 5.5.1)を使うと問題なく動作しました。
ちなみに、Cプログラムからscilabの機能を使うためには、当然Scilabのヘッダファイルをincludeする必要があります。
$ sudo apt-get install scilab-includeこれで/usr/include/scilab/以下にヘッダファイルがインストールされます。
Mac OS X 10.9の場合
Mac OS X 10.9の場合、Scilabのバージョンは5.4.1となります。 この環境でilib_for_linkを実行すると、以下のエラーが発生します。-->ilib_for_link('test_inc','test.c',[],"c"); ローダファイルの生成 Makefileの生成 ilib_gen_Make: コンパイルファイル (Makefile*, libtool...) を TMPDIRにコピーしました Makefile を実行中 !--error 246 関数は指定した引数型に関して定義されていません. 引数を確認もしくはオーバーロード用の関数 %s_grep を定義してください. at line 104 of function ilib_compile called by : at line 94 of function ilib_for_link called by :
これは既知のバグです。パッチが公開されています。
パッチは、/Applications/scilab-5.4.1.app/Contents/MacOS/share/scilab/modules/dynamic_link/macros/ilib_compile.sciを、以下のように修正します。
- if (GCClibpath <> "" & ierr == 0 & grep(getenv("LD_LIBRARY_PATH"),GCClibpath) == []) then + + if (GCClibpath <> "" & GCClibpath <> [] & ierr == 0 & grep(getenv("LD_LIBRARY_PATH"),GCClibpath) == [])上記の修正を行ったら、マクロをリビルドします。 Scilab上で以下のコマンドを実施します。
--> exec /Applications/scilab-5.4.1.app/Contents/MacOS/share/scilab/modules/dynamic_link/macros/buildmacros.sceこれでilib_for_linkが正しく動作するはずです。
-->ilib_for_link('test_inc','test.c',[],"c"); ローダファイルの生成 Makefileの生成 ilib_gen_Make: コンパイルファイル (Makefile*, libtool...) を TMPDIRにコピーしました ilib_gen_Make: TMPDIRのMakefileを修正しました。 Makefile を実行中 クリーナ・ファイルの生成