ExSharp

Call C# code from Elixir!

Note: requires C# Interactive (csi.exe) to be installed and included in your path

Installation

If available in Hex, the package can be installed as:

  1. Add ex_sharp to your list of dependencies in mix.exs:

    def deps do

     [{:ex_sharp, "~> 0.0.1"}]

    end

  2. Ensure ex_sharp is started before your application:

    def application do

     [applications: [:ex_sharp]]

    end

Usage

Using the following C# code in Foo.csx:

using System;
using ExSharp;

[ExSharpModule("Foo")]
public static class Foo 
{
  [ExSharpFunction("pi", 0)]
  public static ElixirTerm Pi(ElixirTerm[] argv, int argc) 
  {
    return ElixirTerm.MakeDouble(3.14159);
  }

  [ExSharpFunction("echo", 1)]
  public static ElixirTerm Baz(ElixirTerm[] argv, int argc) 
  {
    var str = ElixirTerm.GetUTF8String(argv[0]);
    return ElixirTerm.MakeUTF8String($"from csharp: {str}");
  }
}

var runner = new ExSharp.Runner();
runner.Run();

Create an ExSharp.Roslyn process with it’s first argument being the path to said .csx script. It is recommended that this process be supervised.

  Path.expand("../priv/Foo.csx", __DIR__)
  |> ExSharp.Roslyn.start_link

The following functions will become available at runtime:

  1. Foo.pi/0
  2. Foo.echo/1

Supported Types

So far the following Elixir types are able to be retrieved/returned from C# code:

C# API

Declare Module and Functions

[ExSharpModule(module_name)]
public static class ModuleName
{
  [ExSharFunction(function_name, arity)]
  public static ElixirTerm Foo(ElixirTerm[] argv, int argc) 
  {
    ...
  }

  [ExSharFunction(function_name, arity)]
  public static void Foo(ElixirTerm[] argv, int argc) 
  {
    (functions that return void will return `:ok`)
    ...
  }
}

Type Conversions

Custom C# Types

Read only properties:

#### Tuple Usage

  Tuple t = ElixirTerm.GetTuple(argv[0]);
  string a = ElixirTerm.GetAtom(t[0]);
  string s = ElixirTerm.GetUTF8String(t[1]);