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]);

Elixir Callbacks From C#

You can call elixir functions or set up events to trigger them by using ExSharp.Runner.ElixirCallback(fun, args).

fun is an ElixirTerm with tag TagType.NEW_FUN or TagType.EXPORT.

Examples

[ExSharpFunction("call", 0)]
public static void Call(ElixirTerm[] argv, int argc)
{
ExSharp.Runner.ElixirCallback(argv[0], new ElixirTerm[0]);
}
iex> fun = fn -> IO.puts "Hi!" end
iex> Foo.call(fun)
iex> :ok
iex> HI