.net clojure clojureclr

Llamando a Clojure desde.NET



clojureclr (2)

He pasado algún tiempo jugando con Clojure-CLR. Mi REPL está funcionando, puedo llamar a clases .NET desde Clojure, pero no he podido averiguar cómo llamar a las dlls compiladas de Clojure desde clases C #.

He estado tratando de adaptar el ejemplo de java encontrado here:

Eliminé la línea: name de la parte superior del ejemplo porque causa un error "Duplicate key:: name". Sin la línea ": name", el código se compila bien y puedo agregar la referencia en Visual Studio, pero parece que no puedo entender cómo usar el código. He intentado una variedad de declaraciones ''de uso'', pero hasta ahora nada ha funcionado. ¿Alguien puede dar un poco de información sobre esto? Aquí está el código de Clojure que estoy tratando de usar.

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


Pude hacerlo funcionar haciendo lo siguiente:

Primero cambié un poco tu código, tenía problemas con el espacio de nombres y el compilador pensando que los puntos eran directorios. Así que terminé con esto.

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

A continuación lo compilé llamando:

Clojure.Compile.exe hello

Esto crea varios archivos: hello.clj.dll, hello.clj.pdb, hello.exe y hello.pdb Puede ejecutar hello.exe y debería ejecutar la función -main.

Luego creé una aplicación de consola C # simple. Luego agregué las siguientes referencias: Clojure.dll, hello.clj.dll y hello.exe

Aquí está el código de la aplicación de consola:

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

Como puede ver, debe poder crear y utilizar la clase hello, que reside en el ensamblaje hello.exe. No soy el motivo por el que la función "salida" no es estática, supongo que es un error en el compilador CLR. También tuve que usar la versión 1.2.0 de ClojureCLR, ya que la última no estaba encontrando excepciones para el ensamblado.

Para ejecutar la aplicación, asegúrese de establecer la variable de entorno clojure.load.path en el lugar donde residen sus archivos binarios de Clojure.

Espero que esto ayude.


Yo diría que deberías tomar otra medida en esto. Todas esas cosas gen-class solo existen en clojure como un truco para decirle al compilador cómo generar clases envolventes de Java / C # en torno a las variables dinámicas reflexivas de clojure nativas.

Creo que es mejor hacer todas las cosas de "clase" en C # y mantener su código de clojure más nativo. Tu elección. Pero si quieres ir por este camino, escribe una envoltura como esta:

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

De esa manera tu C # puede lucir como C # normal

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

Y el clojure puede verse como clojure normal:

(ns code.clojure.example.hello) (defn output [a b] (+ a b))

Esto funcionará si lo compilas o simplemente lo dejas como un script. (RT.load ("hello") cargará el script hello.clj si existe, o de lo contrario cargará el ensamblaje hello.clj.dll).

Esto permite que su clojure se vea como clojure y que su C # se vea como C #. Además, elimina el error estático del compilador de interoperabilidad clojure del método (y cualquier otro error de interoperabilidad que pueda existir), ya que estás evitando completamente el compilador de interoperabilidad clojure.