最近Rubyからdllとかsoとか、割と簡単(?)に呼び出せることを知りました。
自分のやったことを整理しています。
C側(呼び出す対象->よくわかっていない)
sample.cpp
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
//社員の給与
typedef struct salary {
long amount;
long family;
long bonus;
} SAL;
// 社員構造体
typedef struct employee {
long no;
char name[20];
int service;
SAL salary;
} EMP;
int main(void)
{
struct employee e[20]= {
{ 1, "将来 有望",5, 201234, 10000, 350123 },
{ 0, "", 0, 0, 0,0 },
};
struct employee *emp;
int i;
emp = e;
for(i = 0; emp->no != 0; i++) {
printf("%s total = %ld\n",
emp->name,
emp->salary.amount + emp->salary.family);
emp++;
}
return 0;
}
extern "C" int call(EMP *a,EMP *b){
printf("a-size : %lu\n",sizeof(*a));
printf("b-size : %lu\n",sizeof(*b));
//渡された名前をかくにん
printf("%s\n",a->name);
EMP *c;
//構造体配列
c = (EMP *)malloc(sizeof(EMP) * 5);
c = b;
//rubyから渡した値をコピー
c[0].no = a->no;
strcpy(c[0].name,a->name);
c[0].salary.amount = a->salary.amount;
c[1].no = 77777;
strcpy(c[1].name,"薄給 涙");
c[1].salary.amount = 170077;
//値の変更
strcpy(a->name,"test_name_moded");
return 1;
}
ビルド(MACで実行した)
gcc -shared sample.cpp -o lib_sample.so
call_.rb
require "fiddle/import"
module M
extend Fiddle::Importer
dlload "./lib_sample.so"
extern "int main()"
extern "int call(void *,void *)"
#構造体の入れ子はバラすのがポイント(と聞いた)
EMP = struct(["long a","char b[20]","int c","long x","long y","long z",])
end
x = M::EMP.malloc
y = Fiddle::Pointer.malloc(M::EMP.size * 5)
x.a = 1
x.b = "test name".unpack("c*") + [0] * (20 - 4)
x.c = 1
x.x = 100000
M.call(x,y)
p "x:"
p x.b.pack("c*").force_encoding("utf-8")
p "x[0] = a:#{x.a},b:#{x.b.pack("c*")},x:#{x.x}"
y_ret = M::EMP.new(y)
p "y[0] = a:#{y_ret.a},b:#{y_ret.b.pack("c*")},x:#{y_ret.x}"
# ポインタずらし
yp = y + M::EMP.size
y_ret2 = M::EMP.new(yp)
p "y[1] = a:#{y_ret2.a},b:#{y_ret2.b.pack("c*").force_encoding("utf-8")},x:#{y_ret2.x}"
実行結果.
"x[0] = a:1,b:test_name_moded\u0000\u0000\u0000\u0000\u0000,x:100000"
"y[0] = a:1,b:test name\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000,x:100000"
"y[1] = a:77777,b:薄給 涙\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000,x:170077"
あまりわかってない感が満載でした。以上。