我有第三方.NET程序集和一个大型Java应用程序。我需要从Java应用程序调用.NET类库提供的方法。程序集未启用COM。 我搜索过网络,到目前为止,我有以下内容:
C#代码(cslib.cs):
using System;
namespace CSLib
{
public class CSClass
{
public static void SayHi()
{
System.Console.WriteLine("Hi");
}
}
}
编译(使用.net 3.5,但使用2.0时也是如此):
csc /target:library cslib.cs
C ++代码(clib.cpp):
#include <jni.h>
#using <CSLib.dll>
using namespace CSLib;
extern "C" _declspec(dllexport) void Java_CallCS_callCS(JNIEnv* env, jclass cls) {
CSLib::CSClass::SayHi();
}
编译(使用VC 2008工具,但使用2003工具时也是如此):
cl /clr /LD clib.cpp
mt -manifest clib.dll.manifest -outputresource:clib.dll;2
Java代码(CallCS.java):
class CallCS {
static {
System.loadLibrary("clib");
}
private static native void callCS();
public static void main(String[] args) {
callCS();
}
}
当我尝试运行java类时,Java VM在调用方法时崩溃(它能够加载库):
# #Java Runtime Environment检测到意外错误: # #Internal Error(0xe0434f4d),pid = 3144,tid = 3484 # #Java VM:Java HotSpot(TM)客户端VM(10.0-b19混合模式,共享windows-x86) #有问题的框架: #C [kernel32.dll + 0x22366] # ... Java框架:(J =编译的Java代码,j =解释,Vv = VM代码) j CallCS.callCS()V + 0 j CallCS.main([Ljava / lang / String;)V + 0 v~StubRoutines :: call_stub
但是,如果我创建一个加载clib.dll并调用导出函数Java_CallCS_callCS的普通cpp应用程序,一切正常。 我在x86和x64环境中尝试了这个,结果是一样的。我没有尝试过其他版本的Java,但我需要在1.5.0上运行代码。
此外,如果我修改clib.cpp只调用System方法,即使从Java也可以正常工作:
#include <jni.h>
#using <mscorlib.dll>
using namespace System;
extern "C" _declspec(dllexport) void Java_CallCS_callCS(JNIEnv* env, jclass cls) {
System::Console::WriteLine("It works");
}
总结:
- 我可以从Java调用系统方法 - > clib.dll - > mscorlib.dll
- 我可以从CPPApp调用任何方法 - > clib.dll - > cslib.dll
- 我无法从Java调用任何方法 - > clib.dll - > cslib.dll
我知道一个使用1.上面的解决方法 - 我可以使用反射加载assmeble并仅使用系统调用调用所需的方法,但代码变得混乱,我希望有更好的解决方案。
我知道dotnetfromjava项目,它使用反射方法,但不希望增加比所需更多的复杂性。但是,如果没有别的办法,我会用这样的东西。
我也看了ikvm.net,但我的理解是它使用自己的JVM(用C#编写)来实现魔力。但是,在我的VM下运行整个Java应用程序是没有选择的。
谢谢。