Pipe to python process from c# unity

I have a unity (C#) app that is calling a python script by initialising a child process.

When trying to write to the python std::in, I seem to be getting a

write fault on path

error when writing to STD::IN.

When reading from the process's STD::OUT, I get null as a value output.

What's the best way to pipe to the python process for input/output?

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 CODE:

print('hello world!')

2 answers

  • answered 2018-10-11 19:54 shapov

    I think you need to redirect standard input for this to work. You already have that line, it's just commented out.

    process.StartInfo.RedirectStandardInput = true;
    

    Check this MSDN example for more info.

  • answered 2018-10-11 20:04 Woody1193

    The way you're writing to StandardInput from the C# side is how I would expect it to work, given this and assuming that you already tried to run your method with process.StartInfo.RedirectStandardInput set to true. So, the only way I could see this not working is if your Python code (which you should attach to the question) wasn't reading stdin properly.

    According to this, you can do that by either reading sys.stdin like a file, prompting the user for input or getting command-line arguments. Since you stated that your Python program is currently running, my guess is that you want to use either read or readlines to do that. Note that after you've done that you should uncomment process.StartInfo.RedirectStandardInput = true;.