简体   繁体   English

使用JNA从Java调用带有类和子功能的VB.Net dll

[英]Call VB.Net dll with classes and subfunctions, from Java with JNA

I have a third-party VB.Net dll that I want to call from Java . 我有一个想从Java调用 的第三方VB.Net dll

The VB.Net dll has the following signature (pseudo code, but feels like 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;
    }
}

Note: StringRef is my way of saying the method expects me to pass in strings by reference. 注意: StringRef是我说方法希望我通过引用传递字符串的方式。

I am trying to call this dll object from within Java. 我试图从Java内部调用此dll对象。 Using JNA, I have the following: 使用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);
    }
}

The INSTANCE object here loads just fine. 这里的INSTANCE对象可以很好地加载。 However, I cannot figure out what structure the body of DllName should take to map to the dll's class, method signature. 但是,我无法弄清楚DllName主体应采用什么结构来映射到dll的类,方法签名。 Also, I have not seen how I might call Native in a way that would load the object directly. 另外,我还没有看到如何直接加载对象的方式调用Native For example, if I do: 例如,如果我这样做:

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

This results in an UnsatisfiedLinkError since the dll is named DllName . 由于dll名为DllName因此将导致UnsatisfiedLinkError Making this call requires a different interface than shown above. 进行此调用所需的接口与上面显示的接口不同。

Questions : 问题

  1. Is this even possible? 这有可能吗? Eg Can I call a VB.Net dll from Java using JNA given the structure above. 例如,根据上述结构,我可以使用JNA从Java调用VB.Net dll吗?
  2. What structure does DllName need to have to properly map to the class MyClass1 and MyClass2 ? DllName必须具有什么结构才能正确映射到类MyClass1MyClass2 This is my core question here. 这是我的核心问题。
  3. In the DllName.MyClass1 call above, is there some alternative way? 在上面的DllName.MyClass1调用中,是否有其他替代方法?
  4. Did I miss anything with any of the alternative items mentioned below? 我是否会错过以下提及的其他替代品? Perhaps some other solution I missed? 也许我错过了其他解决方案?

I have explored the following alternatives : 我探索了以下替代方案

  1. Reviewed this article , but did not see an example that matches my structure. 阅读了本文 ,但没有看到符合我的结构的示例。 I also looked at the unit tests referenced on the bottom. 我还查看了底部引用的单元测试。
  2. Creating a C++ wrapper, as suggested here /questions/1556421/use-jni-instead-of-jna-to-call-native-code (I'd post as a link, but not enough reputation with SO...). 按照此处的建议/ questions / 1556421 / use-jni-instead-of-jna-to-call-native-code的建议创建一个C ++包装器(我将其发布为链接,但在SO中的声誉不高...)。 I haven't actually tried this, as I am not familiar with C++. 我实际上还没有尝试过,因为我不熟悉C ++。 I would expect too-much head-banging, when I think some change to my Java code would suffice. 当我认为对Java代码进行一些更改就足够了时,我会感到头疼。
  3. JNI: This seems like it is only for C/C++ type dlls. JNI:这似乎仅适用于C / C ++类型的dll。
  4. javOnet: Almost works, but the VB.Net methods expect strings by reference, which is not currently supported by javOnet. javOnet:几乎可以使用,但是VB.Net方法希望通过引用来获取字符串,而javOnet目前不支持。 I reported the issue to them, and I expect a fix. 我向他们报告了该问题,希望得到修复。 Even if it did work, it seems like a JNA solution should work. 即使它确实起作用,似乎JNA解决方案也应该起作用。 There is also a cost issue with that solution. 该解决方案也存在成本问题。
  5. jni4net: This does not work for me since this is a third-party dll. jni4net:这对我不起作用,因为这是第三方dll。 jni4net expects some hook on the .Net side. jni4net希望在.Net方面有所了解。

Please let me know if you would like me to add any additional color here. 如果您要我在此处添加其他颜色,请告诉我。

javOnet already provides support for arguments passed by ref or out since version 1.2. 自1.2版以来,javOnet已经支持通过ref或out传递的参数。 You can read more at: http://www.javonet.com/quick-start-guide/#Passing_arguments_by_reference_with_ref_and_out_keywrods 您可以在以下位置阅读更多信息: http : //www.javonet.com/quick-start-guide/#Passing_arguments_by_reference_with_ref_and_out_keywrods

You must wrap you JAVA type in "AtomicReference" so it can be updated within the method call and your JAVA variable let's say integer will be automatically modified on .NET side. 您必须将JAVA类型包装在“ AtomicReference”中,以便可以在方法调用中进行更新,并且您的JAVA变量(例如,整数)将在.NET端自动进行修改。 You can see the usage sample below: 您可以在下面看到用法示例:

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.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM