从.NET调用Clojure
我一直在玩Clojure-CLR。我的REPL工作正常,我可以从Clojure调用.NET类,但是我一直无法从C#类中调用编译的Clojure dll。从.NET调用Clojure
我一直在努力适应Java示例发现here:
我删除了:从示例上方的姓名线,因为它会导致“重复键:名称”的错误。没有“: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))
我能得到它的工作执行以下操作:
首先,我改变了你的代码了一下,我是有命名空间的麻烦和编译器思考点是目录。所以我结束了这一点。
(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程序集中。我不是为什么函数“输出”不是静态的,我认为这是CLR编译器中的一个错误。我也不得不使用ClojureCLR的1.2.0版本作为最新的抛出程序集,没有发现异常。
为了执行应用程序,请确保将clojure.load.path环境变量设置为Clojure二进制文件所在的位置。
希望这会有所帮助。
我认为你应该采取另一个方法来解决这个问题。所有那些gen-class的东西只存在于clojure中,作为一种黑客来告诉编译器如何围绕本地clojure反射动态变量生成包装Java/C#类。
我认为最好在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互操作编译器。
+1。我喜欢这种方法,并赞同你的推理。还有一些关于链接到EXE的感觉错误。 – harpo 2013-01-15 23:23:39