【问题标题】:What is the fastest and easiest way to call a C function from Erlang via ports?通过端口从 Erlang 调用 C 函数的最快和最简单的方法是什么?
【发布时间】:2011-12-03 05:13:47
【问题描述】:

Francesco Cesarini 的“Erlang Programming”一书提供了一个很好且易于上手的示例,将 Erlang 连接到 Ruby(通过端口实现):

module(test.erl).
compile(export_all).    

test() ->
    Cmd = "ruby echoFac.rb",
    Port = open_port({spawn, Cmd}, [{packet, 4}, use_stdio, exit_status, binary]),
    Payload = term_to_binary({fac, list_to_binary(integer_to_list(23))}),
    port_command(Port, Payload),
    receive
     {Port, {data, Data}} ->
      {result, Text} = binary_to_term(Data),
      Blah = binary_to_list(Text),
      io:format("~p~n", [Blah])
    end.

但是,本示例中使用的 Ruby 代码使用 Erlictricity 库,它为程序员完成了所有低级操作:

require 'rubygems'
require 'erlectricity'
require 'stringio'
def fac n
if (n<=0) then 1 else n*(fac (n-1)) end
end
receive do |f|
f.when(:fac, String) do |text|
n = text.to_i
f.send!(:result, "#{n}!=#{(fac n)}")
f.receive_loop
end
end

我尝试使用这个稍作修改的 test.erl 代码:

test(Param) ->
        Cmd = "./add",
        Port = open_port({spawn, Cmd}, [{packet, 4}, use_stdio, exit_status, binary]),
        Payload = term_to_binary({main, list_to_binary(integer_to_list(Param))}),
...

用一个非常简单的 C 文件来说话:

/* add.c */
#include <stdio.h>
int main(int x) {
 // return x+1;
 printf("%i\n",x+1);
}

但不幸的是,test.erl 中的接收循环收到了一条消息{#Port&lt;0.2028&gt;,{exit_status,2}}

我的问题是:是否可以在 C/C++ 中实现类似的东西? 是否有任何现成的 Erlang 库可以通过类似于 Erlictricity for Ruby 的端口与 C/C++ 对话?

【问题讨论】:

  • 一个关键点是你想在 Erlang 和 C 之间传递什么样的数据。只是字符串(或一般的二进制 blob)、整数还是浮点数?或者您想将结构化数据(如任意 Erlang 元组)发送到 C 端? C 代码应该向 Erlang 返回什么 - 只是一个状态代码、一个字符串、整数或浮点数,还是应该产生一些复合数据结构?
  • 它可以是我想从 Erlang 传递给 C 的整数和浮点数列表或元组列表(包含整数和浮点数元素)。C 端应该返回整数列表或带整数的元组列表元素。
  • 在这种情况下,您实际上并不需要任何库的帮助(和开销)。只需设计一个非常简单的协议并来回发送原始字节。
  • 亲爱的 RichardC,谢谢!不幸的是,我对 Unix(以及实际上在任何操作系统)上的语言之间的通信知识非常有限。您能否在我可以阅读这种语言对语言交流的地方参考我?我现在知道的唯一两件事是(a)使用临时协议,我定义了双方传递数据的形式,以及(b)我可能可以从 Erlang 调用带有字符串化参数的 shell 命令(如“. /add X",其中 X 来自 Erlang 变量)。
  • RichardC,您能否发表您的最后一条评论作为答案?我会将其标记为已接受。

标签: c++ c erlang erlang-ports


【解决方案1】:

首先阅读 Erlang/OTP 在线文档中的互操作性教程:http://erlang.org/doc/tutorial/users_guide.html。与 C 程序通信时,您只需编写 C 代码以从标准输入读取并写入标准输出,这将连接到 Erlang 端口。你也可以在http://manning.com/logan阅读第12章。

【讨论】:

    【解决方案2】:

    您是否在此处查看过Erl Interface@987654321@
    我发现的其他有趣的链接如下:

    http://www.erlang.org/documentation/doc-4.9.1/pdf/erl_interface-3.2.pdf
    http://www.erlang.org/doc/apps/erl_interface/index.html
    http://dukesoferl.blogspot.com/2010/01/minor-erlang-interface-tricks.html b>

    我希望这些会有所帮助:)

    【讨论】:

    • 我已经阅读了它,我不得不承认我无法使示例工作(另一方面,Ruby 示例要简单得多)。如果这是唯一的选择,那么我必须花更多的时间:)
    猜你喜欢
    • 1970-01-01
    • 2022-08-13
    • 1970-01-01
    • 2019-05-12
    • 1970-01-01
    • 2010-11-03
    • 2012-02-12
    • 2013-06-24
    • 1970-01-01
    相关资源
    最近更新 更多