Str*_*ill 6 .net c# java com dll
好吧,我一直在挖掘这一段时间,我正在寻找输入.
我需要一个可以加载和卸载本机库的Java应用程序,这很简单,C/C++/Java/Scripts/Executables /等.使用JNI和其他内置功能并不是真正的问题.
但是,我需要能够加载.NET库,这一直是疯狂的沮丧.我的第一个注意事项是使用JNI并调用C++包装器,如下所示:
Java的:
this.Lib = (LibHandler)Native.loadLibrary("MyLib", LibHandler.class);
Run Code Online (Sandbox Code Playgroud)
CPP:
#include <jni.h>
#using <MyLibCSharp.dll>
#include <vcclr.h>
#include <msclr\marshal.h>
using namespace msclr::interop;
using namespace System::Runtime::InteropServices;
using namespace System;
extern "C"
{
JNIEXPORT jstring JNICALL Java_Test(JNIEnv * env)
{
marshal_context ^ context = gcnew marshal_context();
const char* str4 = context->marshal_as<const char*>(CSharp::Class1::Test());
jstring js = env->NewStringUTF(str4);
return js;
}
JNIEXPORT jstring JNICALL Java_Test2(JNIEnv * env, jobject jobj)
{
marshal_context ^ context = gcnew marshal_context();
const char* str4 = context->marshal_as<const char*>(CSharp::Class1::Test());
jstring js = env->NewStringUTF(str4);
return js;
}
}
Run Code Online (Sandbox Code Playgroud)
这将连续无法由系统加载,我可以交换文件,以便MyLib.dll实际上是C#,并且它成功加载它(但无法找到任何函数,因为它不是本机C库,我不要认为.NET可以像C++一样导出),所以我没有文件位置问题.
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'MyLib.dll': The specified module could not be found.
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:163)
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:236)
at com.sun.jna.Library$Handler.<init>(Library.java:140)
at com.sun.jna.Native.loadLibrary(Native.java:379)
at com.sun.jna.Native.loadLibrary(Native.java:364)
at EntryPoint.main(EntryPoint.java:31)
Run Code Online (Sandbox Code Playgroud)
我想我会尝试将C#库编译为COM对象并以这种方式调用它,唉:
ActiveXComponent comp = new ActiveXComponent("MyLib.Class1");
Run Code Online (Sandbox Code Playgroud)
失败:
Exception in thread "main" com.jacob.com.ComFailException: Can't co-create object
at com.jacob.com.Dispatch.createInstanceNative(Native Method)
at com.jacob.com.Dispatch.<init>(Dispatch.java:99)
at com.jacob.activeX.ActiveXComponent.<init>(ActiveXComponent.java:58)
at EntryPoint.main(EntryPoint.java:33)
Run Code Online (Sandbox Code Playgroud)
C#代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace MyLib
{
[Guid("4F3A0A13-4D2B-4DE6-93EA-D6861C230290"),
ComVisible(true)]
public interface ITest
{
[DispId(1)]
string Test();
}
[Guid("A78C5820-3E4B-49B3-8C8E-63DD12346410"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
ComVisible(true)]
public interface ITestEvents
{
}
[Guid("3ECD46AE-E8F4-4B62-B9DC-DD7F6CB435E2"),
ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(typeof(ITestEvents)),
ComVisible(true)]
public class Class1 : ITest
{
public string Test()
{
return "This is my C# DLL COM returning a string! heh!";
}
}
}
Run Code Online (Sandbox Code Playgroud)
我可以看到COM已注册,我可以用oleview.exe浏览它,但是我不能用vbScript调用它...我对那个很困惑,所以我完全没有想法,这真的是整天绞尽脑汁.
我想摆脱COM了,但我需要保持implmentation相当简单的(库不会被我们所开发的,所以我不想一堆C/C++代码放到的VB6开发圈) .
我可以回到CLI C++实现方法,因为它很简单,几乎任何人都可以做到.
任何想法都将非常感谢,谢谢.
编辑:
我不能使用System.LoadLibrary,不要让我卸载像Native.LoadLibrary这样的库与指定的类.
结束了让JNI正确地使用C++代码,我将C++编译为32位,但我正在运行一个64位JVM,这导致了这个非常模糊的错误.
我也遇到了来自.NET的错误(库不在GAC中),所以一定要把它正确地捕获/报告给Java,看来未捕获的异常不能用Java包装我相信.
我可能很快就会在网上发布这个资源,因为许多JNI < - > .NET互操作教程都过于复杂(通常添加看似极其不必要的层).
如果你有单一的方法来揭露你的方法是合理的.定义通过JNI到C++/CLI,然后.NET比尝试使用COM对象处理此类通信更加可靠,更易于维护.
无论如何,对于那些有更复杂要求的人,比如调用任何方法,传递ref/out参数,调用泛型方法,获取设置字段,订阅.NET事件处理异常,获取索引属性等等.我认为自定义本机包装不会工作,至少不是在理性的时间和成本.
如果您有这样的要求或只是想知道可能性,请查看第三方Java到.NET Bridges,如:
如上所述,这两个更适合于这种情况.这些Bridges允许您直接在JAVA代码中使用任何.NET库.它们处理所有提到的操作/场景等等,包括内置数据类型转换和已知陷阱的其他机制.
JNBridge的重量更轻,更贵.但它有一些专用的插件,适用于BizTalk等企业系统.另一方面,Javonet是一款非常轻便的jar文件解决方案,价格非常便宜.另一个主要的区别是Javonet在没有代理类的情况下工作,所以你不必生成任何你只用反射风格调用.NET的包装器,而通过JNBridge,你可以生成代理类,为你提供强类型的接口,但它需要更多的时间和精力.在我看来,它会降低灵活性,因为我喜欢控制在引擎盖下发生的事情,如果你愿意,你可以轻松地制作自己的强类型包装.
我认为这仍然不受欢迎,但对于单机解决方案来说,这是一种很好的方法,可以无缝地覆盖.NET和JAVA之间的差距和原生性能.它只是webservices执行时间百分比的一小部分,不需要任何高级客户端 - 服务器基础结构.在我的测试中,它比直接在.NET中执行特定代码所花费的时间多30%(这非常有吸引力).
很高兴听到你解决你的情况,我希望这篇文章能帮助其他人解决Java到.NET互操作问题.
下面你可以找到使用.NET Random类的Javonet的示例代码(重要的是要注意,使用第三方桥,您不仅可以访问自定义DLL,还可以访问完整的.NET框架):
public void GenerateRandomNumber() throws JavonetException
{
NObject objRandom = Javonet.New("System.Random");
int value = objRandom.invoke("Next",10,20);
System.out.println(value);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6818 次 |
| 最近记录: |