【问题标题】:Pipe to python process from c# unity从 c# unity 到 python 进程的管道
【发布时间】:2018-10-11 19:32:26
【问题描述】:

我有一个统一 (C#) 应用程序,它通过初始化子进程来调用 python 脚本。

当尝试写入 python std::in 时,我似乎得到了一个

write fault on path

写入 STD::IN 时出错。

从进程的 STD::OUT 读取时,我得到 null 作为值输出。

通过管道传输到 python 进程以进行输入/输出的最佳方式是什么?

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using System.Diagnostics;

public class PythonCaller : MonoBehaviour
{
private string buffer = "";
private Process pythonML;

// Use this for initialization
void Start () {
    this.pythonML = new System.Diagnostics.Process();
    this.pythonML.StartInfo.FileName = "/bin/bash";
    this.pythonML.StartInfo.Arguments =
        "{{path to python executable}}/python {{path to python script}}/test.py";
    this.pythonML.StartInfo.UseShellExecute = false;
    this.pythonML.StartInfo.RedirectStandardInput = true;
    this.pythonML.StartInfo.RedirectStandardOutput = true;
    this.pythonML.StartInfo.RedirectStandardError = true;
    this.pythonML.Start();
    this.pythonML.BeginOutputReadLine();
    this.pythonML.OutputDataReceived += new DataReceivedEventHandler((sender, e) => {
        UnityEngine.Debug.Log(e.Data);
    });
    this.pythonML.WaitForExit();
}

// Update is called once per frame
void Update () {
    foreach (char c in Input.inputString) {
        if (c == '\b') {
            if (this.buffer.Length > 0) {
                this.buffer = this.buffer.Substring(0, this.buffer.Length - 1);
            }
        } else if (c == '\n' || c == '\r') {
            try {
                UnityEngine.Debug.Log(this.buffer);
                this.pythonML.StandardInput.WriteLine(this.buffer);

            }
            catch (IOException e) {
                UnityEngine.Debug.Log(e.Message);
            }

            this.buffer = "";
        } else {
            this.buffer += c;
        }
    }
}

}

Python 代码:

print('hello world!')

【问题讨论】:

  • 请添加从标准输入读取的 Python 代码。
  • 您好感谢您的评论,我仍然收到错误 InvalidOperationException:标准输入未重定向 System.Diagnostics.Process.get_StandardInput ()
  • 看起来你的 Python 代码有一个 return 语句,它允许 while 循环只执行一次。因此,您只希望在短时间内接受输入,因此当 C# 代码发送时,Python 代码可能没有接收到
  • 它已被删除,效果甚微(这首先不是原因,因为它在 while 循环之外)。还看了这个没有帮助的stackoverflow.com/questions/2380649/…
  • 这似乎是一个愚蠢的问题,但是您是否尝试过通过此代码进行调试?如果是这样,你能告诉我得到Process之后StartInfo.RedirectStandardInput的值是多少?

标签: c# python unity3d


【解决方案1】:

我认为您需要重定向标准输入才能使其正常工作。你已经有了那行,它只​​是被注释掉了。

process.StartInfo.RedirectStandardInput = true;

查看此MSDN example 了解更多信息。

【讨论】:

    【解决方案2】:

    在给定this 并假设您已经尝试将process.StartInfo.RedirectStandardInput 设置为true 的情况下,您从C# 端写入StandardInput 的方式是我期望它工作的方式。因此,我认为这不起作用的唯一方法是您的 Python 代码(您应该将其附加到问题中)没有正确读取 stdin。

    根据this,您可以通过像文件一样读取sys.stdin、提示用户输入或获取命令行参数来做到这一点。由于您声明您的 Python 程序当前正在运行,我猜您想使用 read 或 readlines 来执行此操作。请注意,完成此操作后,您应该取消注释 process.StartInfo.RedirectStandardInput = true;。

    【讨论】:

      【解决方案3】:

      考虑使用CliWrap。它可以让您以非常有表现力的方式生成子进程和管道输入/输出。

      例如,您可以从二进制流中进行管道传输:

      await using var stream = File.Open("file.bin");
      var command = stream | Cli.Wrap("pythonapp").WithArguments("foo bar");
      
      var result = await command.ExecuteAsync();
      

      更多信息在这里:https://github.com/Tyrrrz/CliWrap#piping

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-21
        • 1970-01-01
        • 2019-12-01
        • 1970-01-01
        • 2011-04-05
        相关资源
        最近更新 更多