我已经提到Erlang Interoperability Tutorial User's Guide并实现了complex.c complex5.erl和port_driver.c
但是可以传递的数据大小限制为1 byte
。
我浏览了文档并在complex5.erl
init(SharedLib) ->
register(code, self()),
Port = open_port({spawn, SharedLib}, [{packet, 4}]),
loop(Port).
更改:传递了元组 {packet, 4}
并在port_driver.c
中进行了以下更改:
static void example_drv_output(ErlDrvData handle, char *buff,
ErlDrvSizeT bufflen) {
example_data* d = (example_data*)handle;
char fn = buff[0], res;
char arg[100];
getAddress(buff, arg);
if (fn == 1) {
res = foo(arg);
} else if (fn == 2) {
res = bar(arg);
}
driver_output(d->port, &res, 4);
}
更改: driver_output(d->port, &res, 4);
我将代码保留为编码并解码不变:
encode({foo, X}) -> [1, X];
encode({bar, Y}) -> [2, Y].
decode([Int]) -> Int.
使用背景:
loop(Port) ->
receive
{call, Caller, Msg} ->
Port ! {self(), {command, encode(Msg)}},
receive
{Port, {data, Data}} ->
Caller ! {code, decode(Data)}
end,
loop(Port);
stop ->
Port ! {self(), close},
receive
{Port, closed} ->
exit(normal)
end;
{'EXIT', Port, Reason} ->
io:format("~p ~n", [Reason]),
exit(port_terminated)
end.
Foo功能:
int foo(int x) {
return 500;
}
但我现在得到错误:
Error in process <0.47.0> with exit value: {function_clause,[{complex,decode,[[252,1,192,135]],[{file,"complex.erl"},{line,62}]},{complex,loop,1,[{file,"complex.erl"},{line,45}]}]}
我是否需要进行任何其他更改,否则,如何从C代码发送整数和接收整数?
编辑:我通过将解码功能修改为以下内容来消除错误:
decode(Int) ->
Bin=list_to_binary(Int),
<<N:32 /integer>> = Bin,
N.
但是现在,当我打电话给foo时,N的值为 4093707712 。
答案 0 :(得分:2)
对port_driver.c的以下修改解决了这个问题。
static void example_drv_output(ErlDrvData handle, char *buff,
ErlDrvSizeT bufflen)
{
example_data* d = (example_data*)handle;
char fn = buff[0], arg = buff[1];
int* res =(int*)malloc(sizeof(int));
if (fn == 1) {
*res = htonl(foo(arg));
} else if (fn == 2) {
*res = htonl(bar(arg));
}
driver_output(d->port, (char*)res, 4);
}
htonl()函数将无符号整数hostlong从主机字节顺序转换为网络字节顺序。
答案 1 :(得分:0)
解码函数在编写时,需要一个完整的元素列表:[Int]
,而消息是4个元素的列表:[252,1,192,135]
。
这不是那么糟糕,因为您似乎成功将消息{self(), {command, encode(Msg)}}
发送到C端口,它已被理解,并且返回的值被解释为{Port, {data, Data}}
,其中Port具有正确的值
查看链接中的代码,当您获得4个整数的列表时,Data应该是一个整数。我想你在驱动程序中做出的修改以及选项{packet, 4}
对此负责。