我正在編寫一個教程,因爲我無法在任何地方找到一個簡單的例子,通過一個端口在Elixir和Rust之間進行通信。使用Elixir通過Ports與Rust交談,我發生了什麼問題?
我可以讓Rustler工作,但這是一個NIF,而不是一個端口。
我在代碼中缺少一些基本的東西。我不確定是否在stdio中缺少基本的東西,或者它是其他東西,但我嘗試了很多不同的東西。
我可以得到端口通信魯斯特一個非常基本的程序協同工作:
defmodule PortExample do
def test() do
port = Port.open({:spawn_executable, "_build/dev/rustler_crates/portexample/debug/portexample"}, [:binary])
Port.info(port)
port
end
:
use std::env;
fn main() {
println!("hello world!");
}
我能得到這個被拉入我的IEX -S運行此端口混合
下面是用於該IEX的樣子:
Interactive Elixir (1.4.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> PortExample.test()
#Port<0.9420>
iex(2)> flush()
{#Port<0.9420>, {:data, "hello world!\n"}}
:ok
iex(3)>
alias Porcelain.Result
def porcelain() do
result = Porcelain.exec("_build/dev/rustler_crates/portexample/debug/portexample",["hello", "world"])
IO.inspect result.out
end
相應IEX:我可以用瓷庫調用做同樣的
iex(3)> PortExample.porcelain()
"hello world!\n"
"hello world!\n"
iex(4)>
然而,當我開始使用防鏽庫某種形式的輸入/輸出,事情開始翻倒。
例如,鏽代碼:
use std::io::{self, Write, Read};
fn main() {
let mut input = String::new();
let mut output = String::new();
for i in 0..2 {
match io::stdin().read_line(&mut input) {
Ok(n) => {
println!("input: {}", input.trim());
io::stdout().flush();
}
Err(error) => println!("error: {}", error),
}
}
}
我能得到它來編譯,並在命令行中運行:
hello
input: hello
world
input: hello
world
然而,當我把它從藥劑端口:
iex(12)> port = PortExample.test()
#Port<0.8779>
iex(13)> Port.command(port, "hello")
true
iex(14)> Port.command(port, "world")
true
iex(15)> Port.command(port, "!")
true
iex(16)> Port.command(port, "more")
true
iex(17)> flush()
:ok
iex(18)> Port.info(port)
[name: '_build/dev/rustler_crates/portexample/debug/portexample',
links: [#PID<0.271.0>], id: 4697, connected: #PID<0.271.0>, input: 0,
output: 15, os_pid: 21523]
我根本沒有收到任何數據!但是,Port.info(port)
調用顯示它收到了15個字節。它只是沒有向港口發佈任何回報。我一直在嘗試閱讀其他代碼,我認爲我做的事情足夠類似,它應該可以工作,但事實並非如此。
我想:也許緩衝區沒有被刷新?所以我沖洗了Rust中的緩衝區。 我想:也許這個循環是懸掛的,所以我將它限制在只有幾次通過。 當我嘗試通過瓷器調用運行相同的代碼時,它掛起。
謝謝!而已。我知道這一定是我失蹤的根本原因。 – aeroegnr