在Java中访问dll方法

6

我试图在 Java 中访问由 C# 编写的 DLL 方法。我正在尝试构建 DLL,以下是代码,生成成功。

using System;
using Microsoft.Win32;


namespace CyberoamWinHelper
{
    public class RegistryAccess
    {        
        public static String getValue(String key)
        {
            RegistryKey rk = Registry.CurrentUser;
            RegistryKey rk1=rk.OpenSubKey("Software\\Test", RegistryKeyPermissionCheck.ReadWriteSubTree, System.Security.AccessControl.RegistryRights.FullControl);
            rk1.SetValue(key, "val1");
            return rk1.GetValue(key).ToString();
        }
        public static void createSubkey(String name)
        {
            RegistryKey rk = Registry.CurrentUser;
            rk.CreateSubKey("Software\\Test");
        }
    }
}

在此之后,我将加载生成的dll文件到我的Java程序中,代码如下:

public class JNI {

    /**
     * @param args the command line arguments
     */
    public native String getValue(String key);    

    public static void main(String[] args) {
        // TODO code application logic here

        try
        {
            System.loadLibrary("CyberoamWinHelper");
            JNI j=new JNI();       
            System.out.println(j.getValue("abc"));
        }
        catch(UnsatisfiedLinkError  e)
        {
            System.out.println("Ex" + e.getMessage());
        }
    }
}

运行此代码后,出现以下错误。
"Exjni.JNI.getValue(Ljava/lang/String;)Ljava/lang/String;"

我不太理解这个错误在说什么,但我想解决它。

我还有一个问题,因为我要调用的方法是一个静态方法,所以它会被这样调用吗?我的意思是,要调用静态方法,我们需要使用

"类名.方法名"

那么这里能够成功调用该方法吗?


@fge:我做了。它不起作用。 - ATR
当然,您知道.NET dll不是标准的dll,它们本身无法与JNI一起使用。 - Hovercraft Full Of Eels
@HovercraftFullOfEels:我不明白你想说什么。 - ATR
仔细看一下...你尝试使用JNI,但甚至没有尝试让Java和本地代码进行通信。在你的Java代码中没有声明本地方法,在你的本地代码中也没有创建JVM...你想要实现什么? - fge
我想在Java中调用用C#编写的dll的方法。我对JNI不是很了解。 - ATR
显示剩余4条评论
4个回答

7
你只能通过JNI调用那些设计为以这种方式调用的方法。你的方法绝对不是这样设计的。很抱歉直言,你所做的事情根本没有成功的可能性 - 它根本不起作用。
有几种方法可以解决这个问题。其中一种是学习JNI以及如何编写实际可用的库。这里是官方参考文献。但使用C#会增加更多的复杂性。
另一种方法是完全放弃JNI,使用更适合你目标的机制来访问方法。你可以在这里了解JNA;它会更适合你的需求。

1
@ankur-trapasiya - Ernest Friedman-Hill的建议是绝对、完全正确的!请听从他的意见! - paulsm4
@paulsm4:我正在尝试使用JNA来完成它。 - ATR

1

0

首先,第一个链接不是我想要做的。它是关于Visual C++和Java的。这可以通过JNI完成,但我想在C#和Java之间进行操作,无论是否使用JNI。而在第二个链接中也没有回答我的问题。 - ATR
1
JNI与C#没有直接的接口,您需要在C#和Java之间创建一个C++存根。 - Ahmed Masud
哦,我为你找到了一个很酷的解决方案。jni4net就像Jayan所指定的那样不错,但是... - Ahmed Masud

0

对编程有关的内容感兴趣吗?这里有一个非常有用的网站:http://www.sahirshah.com/java/jni.html

试试看:

public class myJNI {

/**
 * @param args the command line arguments
 */
 public static native String getValue(String key);    
 static
 {
   System.loadLibrary("CyberoamWinHelper");
 }
 public static void main(String[] args) {
    // TODO code application logic here

    try
    {     
        String myKey = "abc";
        System.out.println(getValue(myKey));
    }
    catch(UnsatisfiedLinkError  e)
    {
        System.out.println("Ex" + e.getMessage());
    }
  }
}

您需要按照上面的链接描述,将dll封装在c ++ dll中。只需使用“javah -jni myJNI”命令生成一个头文件,并构建具有该头文件中找到的函数签名的c ++ dll。

请查看:http://www.codeproject.com/KB/cross-platform/javacsharp.aspx,了解C#中特定的“hello world”示例


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接