FfidlでC言語のエクスポート関数に配列のポインタを渡して内容を書き換えてもらう

なぜかFfidlで配列を引数に渡すサンプルがどこにも見当たらなかったので、作ってみました。

C言語のDLL側のサンプル。
関数pow2は任意の大きさの整数型配列とそのサイズを受け取り、
その配列の各要素を2乗した値に置き換えるものです。

/* pow2.c */
__declspec(dllexport) void pow2(int* out, int sz)
{
    int i;
    for(i = 0; i < sz; i++)
    {
        out[i] = out[i] * out[i];
    }
}

Visual Studioコンソールから以下を実行してコンパイルする。

cl /LD pow2.c

pow2.dllができるので、pow2をTclから実行してみる。

package require Ffidl
ffidl::callout pow2 {pointer-var int} int [ffidl::symbol pow2.dll pow2]
 
set int_ary {1 2 3 4 5}
set len [llength $int_ary]
set b_ary [binary format i$len $int_ary]
pow2 b_ary $len
 
binary scan $b_ary i$len out_ary
puts $out_ary
#=> 1 4 9 16 25

int_aryの中身が書き換わるわけじゃないです。
int_aryをもとにバイナリ文字列を作り、そのポインタを関数に渡して書き換えてもらいます。
書き換わったバイナリ文字列をスキャンして新しいTclのリストout_aryを得ます。
aryって書いてるけどリストですのであしからず。

DLLの作成で参考にしたページ:
http://marigold.sakura.ne.jp/devel/windows/dll/windll.html

似たようなことしようとしてそうな人:
http://stackoverflow.com/q/5595918/323107

コメントを残す