Calling a Ruby Script in C#

calling a ruby script in c#

void runScript()
{
using (Process p = new Process())
{
ProcessStartInfo info = new ProcessStartInfo("ruby C:\rubyscript.rb");
info.Arguments = "args"; // set args
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
p.StartInfo = info;
p.Start();
string output = p.StandardOutput.ReadToEnd();
// process output
}
}

How can I use Ruby code in .NET?

This is how you do interop:

Make sure you have refs to IronRuby, IronRuby.Libraries, Microsoft.Scripting and Microsoft.Scripting.Core

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IronRuby;
using IronRuby.Builtins;
using IronRuby.Runtime;

namespace ConsoleApplication7 {
class Program {
static void Main(string[] args) {
var runtime = Ruby.CreateRuntime();
var engine = runtime.GetRubyEngine();

engine.Execute("def hello; puts 'hello world'; end");

string s = engine.Execute("hello") as string;
Console.WriteLine(s);
// outputs "hello world"

engine.Execute("class Foo; def bar; puts 'hello from bar'; end; end");
object o = engine.Execute("Foo.new");
var operations = engine.CreateOperations();
string s2 = operations.InvokeMember(o, "bar") as string;
Console.WriteLine(s2);
// outputs "hello from bar"

Console.ReadKey();

}
}
}

Note, Runtime has an ExecuteFile which you can use to execute your file.

To get the Gems going

  1. Make sure you install your gem using igem.exe
  2. you will probably have to set some search paths using Engine.SetSearchPaths

Creating a simple c# dll and access it from ruby

To consume functions from DLLs as done in a Win32 context, these functions need to be export-visible from the DLL. These functions are usually flagged with dllexport and will show up in the export table of a DLL. You can verify that user32 and other Win32 DLLs do this by using a utility such as dumpbin (MSDN).

dllexport, dllimport @ MSDN

Unfortunately, .NET doesn't have immediate support for making functions export-visible, only for bringing in such functions via the DllImport (MSDN) Attribute.

COM is the easiest way to consume code written within .NET from a non-.NET environment, but if you must use the lower level bindings, you can make an intermediate DLL in C, C++/CLI, or any other language and framework combination that can write export headers to a dll, to call your .NET code.

Also, A few articles exist on making this happen via post-compilation automation or other workarounds, here are a few for your reference.

How to Automate Exporting .NET Function to Unmanaged Programs @ CodeProject

Unmanaged Exports @ Google Sites

DllExport - Provides C-style exports for pure .NET assemblies

How to use Ruby and C# together in .Net?

Basically what you are trying to do won't work out-of-the box (define ruby code in a file and directly use it from C# and still get strong typing and Intellisense). Did you forget that Ruby is a weakly typed language?

You could use IronRuby to call ruby code from C#. Here's a step-by-step article illustrating the process. And here's a screencast you could watch.

Call Ruby or Python API in C# .NET

This is one of the two things that the Dynamic Language Runtime is supposed to do: everybody thinks that the DLR is only for language implementors to make it easier to implement dynamic languages on the CLI. But, it is also for application writers, to make it easier to host dynamic languages in their applications.

Before the DLR, every language had their own hosting API. Now, the DLR has a standardized hosting specification that works the same for every language, and with support for dynamically typed objects in C# 4 and VB.NET 10, it gets easier than ever:

// MethodMissingDemo.cs
using System;
using IronRuby;

class Program
{
static void Main()
{
var rubyEngine = Ruby.CreateEngine();
rubyEngine.ExecuteFile("method_missing_demo.rb");
dynamic globals = rubyEngine.Runtime.Globals;

dynamic methodMissingDemo = globals.MethodMissingDemo.@new();

Console.WriteLine(methodMissingDemo.HelloDynamicWorld());

methodMissingDemo.print_all(args);
}
}

# method_missing_demo.rb
class MethodMissingDemo
def print_all(args)
args.map {|arg| puts arg}
end

def method_missing(name, *args)
name.to_s.gsub(/([[:lower:]\d])([[:upper:]])/,'\1 \2')
end
end

Here you see stuff getting passed around in every possible direction. The C# code is calling a method on the Ruby object which doesn't even exist and the Ruby code is iterating over a .NET array and printing its contents to the console.



Related Topics



Leave a reply



Submit