2009-09-23 30 views
3

私はLuainterface 2.0.3を使用してC#アプリケーションにLuaを埋め込みました。Embedded Lua "print"がVisual Studioのデバッグモードで動作しない

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!'"); 
     } 
    } 
}  

印刷が正常に動作しています。

何か不足していますか?

ありがとうございます!

答えて

8

残念ながら、print()関数の既知の不具合に対処している可能性があります。これは本当にコンソールプロンプトで迅速かつ厄介なデバッグを目的としており、必要な柔軟性を欠いています。

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

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

LuaInterfaceが標準Cランタイムの考え方stdoutをどのように処理しようとしているかわかりません。 stdoutはVSデバッガで有用なものには接続されていない可能性が非常に高いかもしれません。デバッグ対象のモジュールからの出力をキャプチャするための.NET機能を利用している可能性があります。

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

2

私はLuaInterfaceを使用していないので、私は確かに言うことはできませんが、Programming in Lua ch 21.1を見て

io.output(io.stdout) 

を呼び出して、手動でしようとする場合があります、彼らはあなたがどこprintの出力をリダイレクトする方法を説明io.outputを設定します。 IO Library Tutorialも参照してください。

io.outputに関連するものがthe LuaInterface source on Google Codeに設定されていないため、実際に問題が解決するかどうかは不明です。

1

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

でファイル "LUAの/ etc/luavs.bat"

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

でライン7を交換し、MSVCRTのデバッグバージョンでLUAを再コンパイル。その後、あなたの出力は期待どおりにリダイレクトされます。ここ

2

Luaの印刷機能をリダイレクトするLuaInterfaceに使用LuaDLLクラスを使用する方法のサンプルコード:

// 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; 
} 

LUAの初期化C#の外観のように:

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)); 
関連する問題