0

So, I'm trying to implement Lua as a scripting language in C#. It's simple enough, really, if you use it as part of a console application. But I want to be able to create a game console within XNA. The problem is that Lua.DoString() seems to return a console line, rather than a string - which, as I said, is fine for console applications, but I want to add it to an output buffer as a string so I can display it in-game, rather than in a console window. I apologize if this is confusing - hopefully the code will clear it up.

using System;
using System.Collections.Generic;
using LuaInterface;

namespace LuaConsoleLibrary
{
    public class LuaConsole
    {
        private Lua lua;

        private bool isRunning = true;
        private string input;
        private List<string> outputBuffer;

        public bool IsRunning
        {
            get { return isRunning; }
        }

        public LuaConsole()
        {
            this.lua = lua;
        }

        public void Run()
        {
            int i = 0;
            while(isRunning)
            {
                outputBuffer.Add("> ");

                input = Console.ReadLine();
                outputBuffer.Add("");

                try
                {
                    lua.DoString(input);
                }
                catch(Exception e)
                {
                    outputBuffer.Add(e.Message);
                }
                finally
                {
                    outputBuffer.Add("");
                }
            }
        }
    }
}

Basically, I'm confused as to why lua.DoString(input); should work as opposed to having to use Console.WriteLine(lua.DoString(input));. I've even tried outputBuffer.Add(lua.DoString(input).ToString());, which, being that ToString is valid there, should work in theory. Instead it performs lua.DoString and then throws an exception - "Object reference not set to an instance of an object". Unless I'm mistaken, the object in question is Lua, which makes lua a valid object reference. Anyway, seeing as these two solutions don't work, I was wondering if anyone knows enough about LuaInterface to suggest an alternative way to get the same result. I essentially want something to the effect of outputBuffer.Add(lua.DoString(input));. By the way, the Lua command I've been using to test this is print("test") - maybe print is somehow returning a console line instead of a string, but I can't think of another way to return a string from Lua.

I apologize if my problem is rambling or poorly explained - I tried to be as concise as possible, but it's kind of a niche issue and I don't know how else to explain it, really. Oh, and I did try Google, and I browsed all 65 or so LuaInterface questions on Stack Overflow, so I'm 95% sure I've done my due diligence before asking this question. LuaInterface is just not that well-known of a tool, I guess.

bpunsky
  • 73
  • 8
  • Don't you need a `new Lua()` at some point? Otherwise, `lua` always a null reference. `this.lua = lua` is just assigning the field `lua` to itself and there should be compiler warning there. – Mike Zboray Aug 12 '13 at 22:11
  • ^ I think he's right on this one. You're not doing anything in that constructor. – Shotgun Ninja Aug 12 '13 at 22:16
  • Good catch, mike z. I can't believe I didn't notice that myself... but the actual code is (only slightly) more complicated and the Lua instance is passed into the class as a parameter... So, yes, it is a huge problem in my example code, but it definitely doesn't solve my problem. – bpunsky Aug 12 '13 at 22:16
  • This article might help you out some: http://www.dreamincode.net/forums/topic/240886-integrating-lua-with-c%23-using-luainterface/ – Shotgun Ninja Aug 12 '13 at 22:21
  • @mikez - The code as shown (without the mistake you caught) works - but only as a console application. My problem is that I can't see a way to read Lua's output into a string variable in C#, to use it as a graphical input. – bpunsky Aug 12 '13 at 22:26
  • Thank you, @ShotgunNinja, that article will surely help me out as I go along, as reference material, but it doesn't really cover the current issue I have. Nevertheless, it's been bookmarked. - Edit - Sorry, after more careful inspection it seems it DOES have relevant information. Thank you! – bpunsky Aug 12 '13 at 22:28
  • I think this is a problem with the `print` function that people have encountered before, see [this](http://stackoverflow.com/a/1468797/517852). Basically the suggested work around is to override the `print` function to do what you want. – Mike Zboray Aug 12 '13 at 22:53
  • @mikez I don't have the problem specified in that question - it _does_ print to the console, even in debug mode. But I suspect it might be `print()` that's the problem, as you said. It may not be something I can do... I might check out IronPython as an alternative scripting language if I can't resolve this. – bpunsky Aug 12 '13 at 22:57

1 Answers1

1

Object reference not set to instance of an object is C#'s way of saying "something is null and it shouldn't be."

In this case, most likely DoString is returning null, so null.ToString() is raising the exception. You could try outputBuffer.Add(Convert.ToString(lua.DoString(input)[0])) if you want to convert to string without throwing on nulls.

I haven't used either LuaInterface or NLua, but I'd guess that to return a string you'd actually have to execute return "test" as your Lua command.

Jimmy
  • 89,068
  • 17
  • 119
  • 137
  • Yeah, I've abandoned that avenue of approach. I think that .ToString() is a default method of certain objects, even if (as in this case) the object can't inherently be converted into a string. The exception isn't the real problem I have though. – bpunsky Aug 12 '13 at 22:39
  • ToString is a virtual method on `object` and every well-written class should have a non-throwing implementation. But it wont' protect you from dereferencing a null. – Jimmy Aug 12 '13 at 22:41
  • I tried your idea about using `return "test"` and it doesn't exactly _work_, but the results are intriguing to say the least. It prints "System.Object[]" to the console. I took a look at the `Lua.DoString()` source and it does indeed have a return type of `Object[]`. I have no idea how an array of generic objects translates into a console line... Anyway, thanks for the suggestion. – bpunsky Aug 12 '13 at 22:47
  • `return "test"` will return an object array, the first element of which is a string. did you see my edit? Namely, you can extract the first element with [0] and then convert to a string. For more robust code, of course, you should definitely check the length of the returned array before extracting the value. – Jimmy Aug 12 '13 at 23:12
  • You are awesome, thank you. I had tried the `exampleObject[0]` thing before, but not with `return()`. I used it with `print()` and got all sorts of problems... but it works as you have described it. Again, thank you! – bpunsky Aug 12 '13 at 23:34