当前位置:  开发笔记 > 编程语言 > 正文

从Java调用.NET程序集:JVM崩溃

如何解决《从Java调用.NET程序集:JVM崩溃》经验,为你挑选了1个好方法。

我有第三方.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 
#using 

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在调用方法时崩溃(它能够加载库):

#
# An unexpected error has been detected by Java Runtime Environment:
#
#  Internal Error (0xe0434f4d), pid=3144, tid=3484
#
# Java VM: Java HotSpot(TM) Client VM (10.0-b19 mixed mode, sharing windows-x86)
# Problematic frame:
# C  [kernel32.dll+0x22366]
#
...
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
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 
#using 

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

我知道上面使用的一种解决方法 - 我可以使用反射加载,只使用系统调用调用所需的方法,但代码变得混乱,我希望有更好的解决方案.

我知道dotnetfromjava项目,它使用反射方法,但不希望添加比所需更多的复杂性.但是,如果没有别的办法,我会用这样的东西.

我也看了ikvm.net,但我的理解是它使用自己的JVM(用C#编写)来实现魔力.但是,在我的VM下运行整个Java应用程序是不可取的.

谢谢.



1> Kcats..:

好的,这个谜就解决了.

JVM崩溃是由未处理的System.IO.FileNotFoundException引起的.抛出异常是因为在调用exe文件所在的文件夹中搜索.NET程序集.

    mscorlib.dll位于全局程序集缓存中,因此可以正常运行.

    CPP应用程序exe与程序集位于同一文件夹中,因此它也可以.

    cslib.dll程序集在java.exe的文件夹中是NEITHER,在GAC中是NOR,所以它不起作用.

似乎我唯一的选择是在GAC中安装.NET程序集(第三方dll确实有一个强名称).


哇谢谢分享这个,我一直试图找出这个完全相同的问题.我真的想避免GAC出于各种原因,所以我找到了一种方法,使用AssemblyResolve事件从您选择的路径手动加载程序集:http://www.devcity.net/Articles/254/1/.aspx .您必须在C++/CLI层中处理此事件,因为尚未加载C#程序集.无论如何,希望这对另一位Google员工有所帮助......
推荐阅读
手机用户2402852307
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有