我知道有三个问题,但我没有找到确切的答案。 我们有一个没有依赖关系的.Net dll(C#)或p / Invoke。所以它是一个完整的.net平台库。 我们的一个客户希望在Java应用程序中使用它。
什么是最好的选择? 我一直在寻找jni4net,它可能是一个完美的解决方案,但它似乎不支持.Net中的泛型(我们的dll使用了大量的泛型字典和集合)
这是JNA的最佳选择吗?
提前致谢
答案 0 :(得分:4)
1)我确实使用jni来允许我的Java代码调用dll。
2)我在Delphi中写了一个瘦的包装器dll,它是我的Java jni代码调用的实际dll。对于那些与Java完全兼容的函数,包装器dll只是作为一个传递,直接调用实际的dll函数并返回返回值。对于那些不兼容的函数,包装器dll定义了与Java兼容的相应方法,并在调用实际的dll之前从Java到Delphi进行了适当的转换。
3)我还在jni调用上面写了一个瘦的包装器对象。同样,在大多数情况下,java包装器直接对jni调用那些在Java和Delphi之间完全兼容的函数。但是,就我而言,我需要传递几个函数来传递Delphi对象。所以,我所做的是定义相应的Java对象。我的Java包装器对象的主要目的是获取这些Java对象,将它们转换为与我的Delphi包装器DLL兼容的参数,然后进行适当的jni调用。另外,对于那些传回一个对象的dll函数,我的java包装器从jni调用中获取了java兼容的返回值,并创建并组合了相应的对象。
这可能听起来像很多工作,但实际上并非如此(我的dll有超过100种方法,以及十几种Delphi对象类型)。当我完成后,编写实际使用dll的Java应用程序代码非常简单。
关于泛型,这可能是个问题。但是,如果在现实生活中,您支持的对象类型的数量相对较少(通常是这样),您可以在包装器中为每个对象类型单独调用。 (这就是我们这些记住Java 2的人在发明泛型之前曾经做过的事情,它工作得很好,即使它不那么优雅。)你的应用程序Java代码可能会使用泛型;包装器将根据传入的实际类型进行适当的调用。
希望这会给你一些关于如何进行的想法。
答案 1 :(得分:1)
要在JAVA中使用.NET DLL,我会说最好的选择是使用像Javonet这样的本机桥。使用这样的桥接器,您只需将.NET dll复制到JAVA项目文件夹并使用一个方法调用加载它,并使用.NET对象,就像它们是JAVA对象一样。您跳过整个本机部分并获得许多内置工具,用于数据类型转换,订阅事件,垃圾收集器,异常和许多其他工具。
使用“Your.dll”的示例代码如下所示:
Javonet.addReference("Your.dll");
NObject yourDotNetObject = Javonet.New("MyDotNetClass");
yourDotNetObject.invoke("FooMethod", arg1, arg2);
//out of the box you get also support for all types, arrays, generics etc
yourDotNetObject.generic(Javonet.getType("String")).invoke("Foo", "sample");
//such code could call following .NET method passing String as T
//void Foo<T>(T arg);
正如您所看到的,使用半反射语法,您可以访问整个.NET世界,包括任何自定义DLL或.NET框架类。手动解决方案是好的,而不是用于学习然后在实际项目中使用,因为它可能需要更多时间来解决所有问题,然后整个项目需要;)
如需更多样品,请检查: http://www.javonet.com/quick-start-guide/