Вызов Clojure из .NET - PullRequest
       17

Вызов Clojure из .NET

20 голосов
/ 07 декабря 2010

Я провел некоторое время, играя с Clojure-CLR. Мой REPL работает, я могу вызывать классы .NET из Clojure, но я не смог понять, как вызывать скомпилированные библиотеки Clojure из классов C #

Я пытался адаптировать найденный пример Java здесь:

Я удалил строку: name из верхней части примера, поскольку она вызывает ошибку «Duplicate key:: name». Без строки ": name" код компилируется нормально, и я могу добавить ссылку в Visual Studio, но я не могу понять, как использовать код. Я пробовал различные выражения «с помощью», но пока ничего не получалось. Может ли кто-нибудь немного рассказать об этом? Вот код Clojure, который я пытаюсь использовать.

(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))

Ответы [ 2 ]

16 голосов
/ 09 декабря 2010

Я смог заставить его работать следующим образом:

Сначала я немного изменил ваш код, у меня возникли проблемы с пространством имен и компилятором, который думал, что точки - это каталоги.Итак, я закончил с этим.

(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))))

Далее я скомпилировал его, вызвав:

Clojure.Compile.exe hello

Это создает несколько файлов: hello.clj.dll, hello.clj.pdb, hello.exe и hello.pdb Вы можете выполнить hello.exe, и он должен запустить функцию -main.

Далее я создал простое консольное приложение C #.Затем я добавил следующие ссылки: Clojure.dll, hello.clj.dll и hello.exe

Вот код консольного приложения:

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();
        }
    }
}

Как видите,у вас должна быть возможность создавать и использовать класс hello, он находится в сборке hello.exe.Я не то, почему функция «output» не является статичной, я предполагаю, что это ошибка в компиляторе CLR.Я также должен был использовать версию 1.2.0 ClojureCLR, так как последняя выбрасывала сборку не найденных исключений.

Чтобы выполнить приложение, убедитесь, что для переменной среды clojure.load.path установлено, где вашаПостоянные двоичные файлы находятся.

Надеюсь, это поможет.

13 голосов
/ 30 декабря 2010

Я бы сказал, что вы должны предпринять еще одну попытку.Все эти вещи класса gen существуют только в clojure как хак, чтобы сказать компилятору, как генерировать Java / C # классы-оболочки для собственных отражающих динамических переменных clojure.

Я думаю, что лучше делать все "классные" вещи в C # и сохранять код clojure более естественным.Твой выбор.Но если вы хотите пойти по этому пути, напишите обертку следующим образом:

using System;
using clojure.lang;

namespace ConsoleApplication {
    static class Hello {
        public static int Output(int a, int b) {
            RT.load("hello");
            var output = RT.var("code.clojure.example.hello", "output");
            return Convert.ToInt32(output.invoke(a, b));
        }
    }
}

Таким образом, ваш C # может выглядеть как обычный C #

using System;

namespace ConsoleApplication {
    class Program {
        static void Main() {
            Console.WriteLine("3+12=" + Hello.Output(3, 12));
            Console.ReadLine();
        }
    }
}

А clojure может выглядеть как обычный clojure:

(ns code.clojure.example.hello)

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

Это будет работать независимо от того, скомпилируете ли вы его или просто оставляете как скрипт.(RT.load ("hello") загрузит скрипт hello.clj, если он существует, или иначе он загрузит сборку hello.clj.dll).

Это позволяет вашей clojure выглядеть как clojure иваш C # похож на C #.Кроме того, он устраняет ошибку статического метода взаимодействия взаимодействия clojure (и любые другие ошибки взаимодействия, которые могут существовать), поскольку вы полностью обходите компилятор взаимодействия clojure.

...