使用Java和JNA调用带有类和子函数的VB.Net dll

时间:2013-08-02 16:41:33

标签: java vb.net dll jna

我有一个第三方VB.Net dll ,我想从Java调用

VB.Net dll具有以下签名(伪代码,但感觉像Java ......):

class MyClass1 {
    public Object method1(StringRef arg1, StringRef arg2) {
        // do something here...
        return someResult;
    }
}
class MyClass2 {
    public Object method2(StringRef arg1, StringRef arg2) {
        // do something here...
        return someOtherResult;
    }
}

注意: StringRef是我说这种方法希望我通过引用传递字符串的方式。

我试图从Java中调用这个dll对象。使用JNA,我有以下内容:

import com.sun.jna.Library;
import com.sun.jna.Native;

public interface DllName extends Library {
    DllName INSTANCE = (DllName)Native.loadLibrary("DllName", DllName.class);

    public static interface MyClass1 {
        public Object method1(String arg1, String arg2);
    }
    public static interface MyClass2 {
        public Object method2(String arg1, String arg2);
    }
}

这里的INSTANCE对象加载得很好。但是,我无法弄清楚DllName的主体应该采用什么结构来映射到dll的类,方法签名。另外,我还没有看到如何以一种直接加载对象的方式调用Native。例如,如果我这样做:

DllName INSTANCE = (DllName)Native.loadLibrary("DllName.MyClass1", DllName.class);

这导致UnsatisfiedLinkError,因为dll名为DllName。拨打此电话需要与上面显示的界面不同。

问题

  1. 这甚至可能吗?例如。根据上面的结构,我可以使用JNA从Java调用VB.Net dll。
  2. DllName需要哪种结构才能正确映射到班级MyClass1MyClass2?这是我的核心问题。
  3. 在上面的DllName.MyClass1调用中,是否有其他替代方式?
  4. 我是否错过了下面提到的任何替代项目?也许我错过了其他一些解决方案?
  5. 我已经探索了以下替代方案

    1. 已审核this article,但没有看到与我的结构相符的示例。我还查看了底部引用的单元测试。
    2. 创建一个C ++包装器,如这里建议/ questions / 1556421 / use-jni-instead-of-jna-to-call-native-code(我发布的链接,但没有足够的声誉与SO .. )。我还没有尝试过这个,因为我不熟悉C ++。当我认为对我的Java代码进行一些更改就足够了时,我会期待太多的抨击。
    3. JNI:这似乎只适用于C / C ++类型的dll。
    4. javOnet:几乎可以工作,但VB.Net方法需要引用字符串,javOnet目前不支持。我向他们报告了这个问题,我期待一个修复。即使它确实有效,似乎JNA解决方案应该有效。该解决方案还存在成本问题。
    5. jni4net:这对我不起作用,因为这是第三方dll。 jni4net期望在.Net方面有一些钩子。
    6. 如果您希望我在此处添加任何其他颜色,请与我们联系。

1 个答案:

答案 0 :(得分:0)

javOnet已经为自1.2版本以来ref或out传递的参数提供了支持。您可以在以下网址阅读更多 http://www.javonet.com/quick-start-guide/#Passing_arguments_by_reference_with_ref_and_out_keywrods

你必须在“AtomicReference”中包装你的JAVA类型,以便它可以在方法调用中更新,你的JAVA变量让我们说整数将在.NET端自动修改。您可以在下面看到使用示例:

NObject refEx = Javonet.New("RefExample");  
//Wrap Java integer in AtomicReference to allow passing by reference  
AtomicReference<Integer> myInt = new AtomicReference<Integer>(10);  

refEx.invoke("Method",new NRef(myInt));  

System.out.println(myInt.get());  
//Output will display number "55" because int passed by reference has been modified within the method body.