简体   繁体   中英

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

I have a that I want to .

The VB.Net dll has the following signature (pseudo code, but feels like 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 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. Using JNA, I have the following:

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. However, I cannot figure out what structure the body of DllName should take to map to the dll's class, method signature. Also, I have not seen how I might call Native in a way that would load the object directly. 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 . Making this call requires a different interface than shown above.

:

  1. Is this even possible? Eg Can I call a VB.Net dll from Java using JNA given the structure above.
  2. What structure does DllName need to have to properly map to the class MyClass1 and MyClass2 ? This is my core question here.
  3. In the DllName.MyClass1 call above, is there some alternative way?
  4. Did I miss anything with any of the alternative items mentioned below? Perhaps some other solution I missed?

:

  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...). I haven't actually tried this, as I am not familiar with C++. I would expect too-much head-banging, when I think some change to my Java code would suffice.
  3. JNI: This seems like it is only for C/C++ type dlls.
  4. javOnet: Almost works, but the VB.Net methods expect strings by reference, which is not currently supported by 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. 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 expects some hook on the .Net side.

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. You can read more at: 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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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