簡體   English   中英

從C#實例化模塊中的ruby類

[英]Instantiating a ruby class that is in a Module from within C#

我試圖重用我在ASP.NET MVC 2項目中寫的一些ruby類。 我遇到的問題是,如果某個類位於模塊中,我似乎無法實例化它。 如果我將類移出模塊,則可以正常工作。 這是我要實例化的類的縮小版本:

module Generator
  class CmdLine
    attr_accessor :options

    def initialize(output)
    end

    def run(args=[])
    end
  end
end

如果注釋掉模塊部分,則可以創建對象。 難道我做錯了什么? 這是C#代碼:

var engine  = Ruby.CreateEngine();
var searchPaths = engine.GetSearchPaths().ToList();
searchPaths.Add(@"c:\code\generator\lib");
searchPaths.Add(@"C:\Ruby-ri-192\lib\ruby\1.9.1");
engine.SetSearchPaths(searchPaths);

engine.ExecuteFile(@"c:\code\generator\lib\generator\generator_cmd_line.rb");
var rubyCmdLineObj = engine.Runtime.Globals.GetVariableNames();
// These lines works when I comment out the module
// var genCmdLineObj = engine.Runtime.Globals.GetVariable("CmdLine");
// var cmdLineObj = engine.Operations.CreateInstance(genCmdLineObj);
// var results = engine.Operations.InvokeMember(cmdLineObj, "run");
//  return Content(results);
var sb = new StringBuilder();
foreach (var name in rubyCmdLineObj)
{
  sb.AppendFormat("{0} ", name);
}

return Content(sb.ToString());

我有一個解決方法-創建一個可以在C#中調用的單獨的類,但是如果不必這樣做,我寧願不這樣做。 任何指導將不勝感激。

@Shay Friedman提出的解決方案是不必要的。

gen.rb

module Generator
  class CmdLine
    attr_accessor :options

    def initialize(output)
        @output = output
    end

    def run(args=[])
        puts "Hello from cmdLine with #{@output} #{args}"
    end
  end
end

尖銳的

void Main()
{
    var engine = Ruby.CreateEngine();
    var buffer = new MemoryStream();
    engine.Runtime.IO.SetOutput(buffer, new StreamWriter(buffer));
    engine.ExecuteFile(@"c:\temp\gen.rb");
    ObjectHandle handle = engine.ExecuteAndWrap("Generator::CmdLine.new('the output')");
    var scope = engine.CreateScope();
    scope.SetVariable("myvar", handle);
    engine.Execute("myvar.run", scope);
    engine.Operations.InvokeMember(handle.Unwrap(), "run", "InvokeMember");
    buffer.Position = 0;
    Console.WriteLine(new StreamReader(buffer).ReadToEnd());
}

輸出

Hello from cmdLine with the output []
Hello from cmdLine with the output InvokeMember

我將創建一個新的IronRuby項目,將您原始的Ruby代碼並將其移植/編譯到.NET庫中。

完全沒有必要大聲疾呼。 您可以從C#中本地調用某些東西。

我知道這是一種破解/解決方法,但是我設法做到了:

將下一個代碼添加到ruby文件的末尾:

def hack(s)
  eval(s)
end

現在,您的C#代碼將如下所示:

var engine = Ruby.CreateEngine();

var scope = engine.ExecuteFile(@"c:\code\generator\lib\generator\generator_cmd_line.rb");

var genCmdLineObj = engine.Execute(String.Format("hack('{0}::{1}')", "Generator", "CmdLine"), scope);
var cmdLineObj = engine.Operations.CreateInstance(genCmdLineObj);
var results = engine.Operations.InvokeMember(cmdLineObj, "run");
return Content(results);

有點駭客,但嘿,行得通! :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM