Scilab > C言語プログラムの利用

更新日 2015-01-24
広告
C言語で実装した関数を、Scilabから呼び出す方法を紹介します。

基本的な手順

基本的な手順は以下です。
  1. C言語で関数を実装
  2. ilib_for_linkコマンドを使い、ビルド
  3. execコマンドで関数をロード
  4. 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. 引数の順番(1はじまり)
  2. 引数の型(intはi, doubleはd、floatはr、文字列はc)

「関数に渡す引数」が複数の場合は、上記3つ組を、連続で指定します。

「関数に渡す引数」を指定したら、次に"out"を指定します。 これは、「この後に返り値の情報を指定しますよ」というおまじないです。

返り値は、以下の3つ引数で指定します。

  1. 返り値の行列の形。単純な値であれば[1,1]です。
  2. 返り値の順番(引数の順番に続く番号)
  3. 返り値の型

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 を実行中
   クリーナ・ファイルの生成
広告
お問い合わせは sweng.tips@gmail.com まで。
inserted by FC2 system