3

私はLuainterface2.0.3を使用してLuaをac#アプリケーションに埋め込みます。

Visual Studioのデバッグモードを除いて、すべてが正常に機能しています。Luaの印刷機能はコンソール(または出力)に書き込まれません。

using System;
using LuaInterface;

namespace Lua1 {
    class Program {
       static void Main(string[] args) {
          Lua lua = new Lua();
          lua.DoString("print 'Hello from Lua!'");
       }
    }
}    

非デバッグモードで実行すると、印刷は正常に機能しています。

私は何かが足りないのですか?

ありがとう!

4

4 に答える 4

8

残念ながら、あなたはおそらくprint()関数の既知の欠陥に直面しています。これは実際にはコンソールプロンプトでの迅速で汚いデバッグを目的としており、必要な柔軟性が欠けています。

lbaselib.cでprint()実装されているベースライブラリ関数は、Cランタイムのストリームを宛先として明示的に使用します。実装ではグローバル変数を明示的に参照するため、リダイレクトする唯一の方法は、そのファイルハンドルをリダイレクトすることです。を呼び出すことで実行できるCプログラム。残念ながら、Luaにはそれを実行できるストックライブラリ関数がありません。luaB_print()stdoutstdoutfreopen(stdout,...)

ioライブラリはliolib.cに実装されています。関数環境を使用して、開いているファイル記述子のテーブルを保持し、初期化中に、、および3つの標準記述子のfile名前のオブジェクトを作成します。また、名前付きの関数を提供し、開いているオブジェクト(またはファイル名が渡された場合は新しく開いたファイル)を指すようにこれら2つの記述子を変更できるようにします。ただし、これらの関数は関数環境テーブルを変更するだけであり、Cランタイムの値のテーブルを変更するために呼び出すことはありません。io.stdinio.stdoutio.stderrio.outputio.inputfilefreopen()FILE

LuaInterfaceが標準のCランタイムのアイデアをどのように処理しようとしているのかわかりませんstdoutstdoutVSデバッガーで役立つものに接続されていない可能性があります。これは、デバッグ中のモジュールからの出力をキャプチャするために.NET機能を利用している可能性があり、いずれの場合もCとの互換性が低い可能性があるためです。

とはいえ、標準print機能の交換は簡単です。LuaInterfaceの既存の機能を使用して、各引数printを呼び出しtostring()、それを.NETのものが標準出力デバイスであるものに渡すという名前のグローバル関数を作成するだけです。

于 2009-09-23T22:09:29.020 に答える
3

私はLuaInterfaceを使用したことがないので、はっきりとは言えませんが、手動で呼び出してみてください。

io.output(io.stdout)

Lua ch 21.1でのプログラミングを見ると、printio.outputを設定することで、の出力がどこに行くかをリダイレクトする方法が説明されています。IOライブラリチュートリアルも参照してください。

ただし、 Google CodeのLuaInterfaceソースに設定されているio.outputに関連するものが見つからないため、これで実際に問題が解決するかどうかはわかりません。

于 2009-09-23T16:29:21.243 に答える
2

LuaInterfaceで使用されるLuaDLLクラスを使用してluaprint関数をリダイレクトする方法のコードサンプルを次に示します。

// See http://medek.wordpress.com/2009/02/03/wrapping-lua-errors-and-print-function/
static int LuaPrint(IntPtr L)
{
  int nArgs = LuaDLL.lua_gettop(L);
  LuaDLL.lua_getglobal(L, "tostring");
  string ret = ""; //this is where we will dump the output
  //make sure you start at 1 *NOT* 0
  for(int i = 1; i <= nArgs; i++)
  {
      LuaDLL.lua_pushvalue(L, -1);
      LuaDLL.lua_pushvalue(L, i);
      LuaDLL.lua_call(L, 1, 1);
      string s = LuaDLL.lua_tostring(L, -1);
      if(s == null)
          return LuaDLL.luaL_error(L, "\"tostring\" must return a string to \"print\"");
      if(i > 1) ret += "\t";
      ret += s;
      LuaDLL.lua_pop(L, 1);
  };
  //Send it wherever
  Console.Out.WriteLine(ret);
  return 0;
}

C#でのluaの初期化は次のようになります。

IntPtr luaState = LuaDLL.luaL_newstate();
LuaDLL.luaL_openlibs(luaState);
LuaDLL.lua_newtable(luaState);
LuaDLL.lua_setglobal(luaState, "luanet");
Lua l = new Lua(luaState.ToInt64());
LuaDLL.lua_register(luaState, "print", new LuaCSFunction(LuaPrint));
于 2010-12-01T02:52:19.280 に答える
1

ファイル「lua/etc/luavs.bat」の7行目を置き換えます

@set MYCOMPILE=cl /nologo /MD /O2 /W3 /c /D_CRT_SECURE_NO_DEPRECATE

@set MYCOMPILE=cl /nologo /MDd /Od /W3 /c /D_CRT_SECURE_NO_DEPRECATE

デバッグバージョンのMSVCRTを使用してluaを再コンパイルします。その後、出力は期待どおりにリダイレクトされます。

于 2010-07-09T17:36:28.123 に答える