Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling Clojure from .NET

Tags:

I have been spending some time playing with Clojure-CLR. My REPL is working, I can call .NET classes from Clojure, but I have not been able to figure out calling compiled Clojure dlls from C# classes.

I have been trying to adapt the java example found here:

I removed the :name line from the top of the example because it causes a "Duplicate key: :name" error. Without the ":name" line, the code compiles fine and I can add the reference in Visual Studio, but I can't seem to figure out how to use the code. I've tried a variety of 'using' statements, but so far nothing has worked. Can anyone provide a little insight on this? Here is the Clojure code I am attempting to use.

(ns code.clojure.example.hello
  (:gen-class
   :methods [#^{:static true} [output [int int] int]]))

(defn output [a b]
  (+ a b))

(defn -output
  [a b]
  (output a b))
like image 590
tltjr Avatar asked Dec 07 '10 18:12

tltjr


1 Answers

I was able to get it to work doing the following:

First I changed your code a bit, I was having trouble with the namespace and the compiler thinking the dots were directories. So I ended up with this.

(ns hello
  (:require [clojure.core])
  (:gen-class
   :methods [#^{:static true} [output [int int] int]]))

(defn output [a b]
  (+ a b))

(defn -output [a b]
  (output a b))

(defn -main []
  (println (str "(+ 5 10): " (output 5 10))))

Next I compiled it by calling:

Clojure.Compile.exe hello

This creates several files: hello.clj.dll, hello.clj.pdb, hello.exe, and hello.pdb You can execute hello.exe and it should run the -main function.

Next I created a simple C# console application. I then added the following references: Clojure.dll, hello.clj.dll, and hello.exe

Here is the code of the console app:

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            hello h = new hello();
            System.Console.WriteLine(h.output(5, 9));
            System.Console.ReadLine();
        }
    }
}

As you can see, you should be able to create and use the hello class, it resides in the hello.exe assembly. I am not why the function "output" is not static, I assume it's a bug in the CLR compiler. I also had to use the 1.2.0 version of ClojureCLR as the latest was throwing assembly not found exceptions.

In order to execute the application, make sure to set the clojure.load.path environment variable to where your Clojure binaries reside.

Hope this helps.

like image 96
TroyC Avatar answered Oct 04 '22 12:10

TroyC