【发布时间】:2015-07-01 06:39:56
【问题描述】:
我正在尝试为 Erlang 编写 Golang 驱动程序,可通过 Erlang 端口访问。
我从 Erlang C 端口示例开始,效果很好:
http://www.erlang.org/doc/tutorial/c_port.html
现在我正在尝试将 C 代码移植到 Golang;只是试图回显一个简单的 'Hello World\n' 消息,使用 '\n' 作为分隔符。
所以我的Golang代码如下:
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter text: ")
bytes, _ := reader.ReadBytes('\n')
os.Stdout.Write(bytes)
}
我可以编译它并从命令行运行它,如下所示:
justin@justin-ThinkPad-X240:~/work/erlang_golang_port$ go build -o tmp/echo echo.go
justin@justin-ThinkPad-X240:~/work/erlang_golang_port$ ./tmp/echo
Enter text: hello
hello
但是,当我尝试从 Erlang 端调用驱动程序(下面的 Erlang 代码)时,我得到以下信息:
justin@justin-ThinkPad-X240:~/work/erlang_golang_port$ erl
Erlang R16B03 (erts-5.10.4) [source] [64-bit] [smp:4:4] [async-threads:10] [kernel-poll:false]
Eshell V5.10.4 (abort with ^G)
1> c(complex1).
{ok,complex1}
2> complex1:start("./tmp/echo").
<0.41.0>
3> complex1:ping().
=ERROR REPORT==== 23-Apr-2015::08:56:47 ===
Bad value on output port './tmp/echo'
我感觉消息可以正常传递给驱动程序,但是我以某种方式错误地返回了响应。
TIA。
Erlang 端口代码:
-module(complex1).
-export([start/1, stop/0, init/1]).
-export([ping/0]).
-define(HELLO_WORLD, [72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 46]).
start(ExtPrg) ->
spawn(?MODULE, init, [ExtPrg]).
stop() ->
complex ! stop.
ping() ->
call_port({ping, ?HELLO_WORLD++[10]}).
call_port(Msg) ->
complex ! {call, self(), Msg},
receive
{complex, Result} ->
Result
end.
init(ExtPrg) ->
register(complex, self()),
process_flag(trap_exit, true),
Port = open_port({spawn, ExtPrg}, [{packet, 2}]),
loop(Port).
loop(Port) ->
receive
{call, Caller, Msg} ->
Port ! {self(), {command, Msg}},
receive
{Port, {data, Data}} ->
Caller ! {complex, Data}
end,
loop(Port);
stop ->
Port ! {self(), close},
receive
{Port, closed} ->
exit(normal)
end;
{'EXIT', Port, _Reason} ->
exit(port_terminated)
end.
【问题讨论】:
-
ping/0使用call_port/1将元组作为消息发送到端口进程,然后将其发送到端口。发送到端口的实际数据只能是字节列表。 -
还有 `fmt.Print("Enter text: ")` 写入标准输出。 erlang 进程意外写入的文本。
-
@rvirding 应该已经发现了;错误地转置了 C 示例。作品。谢谢。
-
请将此问题标记为已回答。
-
@Justin 您可以将工作代码发布为答案并将其标记为答案。这可能会对其他人有所帮助。
标签: go erlang erlang-ports