从Java中使用JNA调用DLLJava、JNA、DLL

2023-09-02 21:40:13 作者:合久必婚,婚久必离

我是新来使用JNA从Java访问的DLL。我需要一个DLL(.NET编写)内的类访问方法。构成本示例DLL下面,我试图让AuditID和服务器ID。我结束与下面的错误,而我正在我的code。任何指导真的AP preciated。

///错误///

 在线程异常主要java.lang.UnsatisfiedLinkError中:错误查找功能GetEnrollcontext:指定的程序无法找到。
 

// DLL文件code //

  SampleDLL.ProfileEnroll enrollcontext =新SampleDLL.ProfileEnroll();
enrollcontext.Url =URL;
enrollcontext.AuditIdType = SampleDLL.ProfileId;
enrollcontext.AuditId =22222222;
enrollcontext.ServerId =服务器1;
 

///的Java code ///

 进口com.sun.jna.Library;
进口com.sun.jna.Native;
进口com.sun.jna.Structure;
进口dllExtract.DLLExtractTest.SampleDLL.Enrollcontext;


公共类SampleDLLExtract {

    公共接口SampleDLL扩展库{
        SampleDLL INSTANCE =(SampleDLL)Native.loadLibrary(SampleDLL
            SampleDLL.class);

        公共静态类Enrollcontext扩展结构{

            公共字符串auditId;
            公共字符串服务器ID;
        }
            无效GetEnrollcontext(Enrollcontext EC); //无效();
    }
    公共静态无效的主要(字串[] args){
        SampleDLL SDLL = SampleDLL.INSTANCE;
        SampleDLL.Enrollcontext enrollContext =新SampleDLL.Enrollcontext();
        sdll.GetEnrollcontext(enrollContext);

        的System.out.println(sdll.toString(sdll.GetEnrollcontext(enrollContext)));
    }
}
 
成都汇智动力 Java调用C 动态链接库dll,VS2015 Ecli

解决方案

其实有一个解决方案,为您在Java中(而不是其他)使用C#,VB.NET和F#code通过JNA!而且它也很容易使用: https://www.nuget.org/packages/UnmanagedExports

本包装所有你需要做的是,添加[RGiesecke.DllExport.DllExport]你的方法那样:

C#的.dll项目:

  [RGiesecke.DllExport.DllExport]
公共静态字符串yourFunction(字符串yourParameter)
{
    返回CSHARP字符串;
}
 

Java项目:

 公共接口JNA扩展库{
    JNA INSTANCE =(JNA)Native.loadLibrary(yourCSharpProject.dll,jna.class);
公共字符串yourFunction(字符串yourParameter);
}
 

使用在code:

 的System.out.println(jna.INSTANCE.yourFunction(nothingImportant));
 

中提琴!

前面已经提到过它的工作原理非常简单,但这种方法有一定的局限性:

仅可用于简单数据类型作为参数及放大器;返回值 在没有可用的MethodOverloading。 yourFunction(字符串yourParameter)和yourFunction(字符串yourParameter,字符串yourSecondParameter)不起作用!你有他们不同的名字 使用数组作为参数或返回值。 (JNA提供字符串数组,但我不能够使用它们在C#中)(也许有一个解决方案,但我不能拿出一个为止!) 如果您导出方法,你可以不在内部在C#code调用它(简单的绕过了以下内容:

  [RGiesecke.DllExport.DllExport]
公共静态布尔externalAvailable(字符串yourParameter)
{
    返回yourInternalFunction(yourParameter);
}
 

使用C#它的伟大工程,用VB.NET和F#我没有经验。 希望这有助于!

I am new to accessing DLLs from Java using JNA. I need to access methods from a class within a DLL(written in .net). Form this sample DLL below, I am trying to get AuditID and Server ID. I am ending with the following error while I am running my code. Any guidance really appreciated.

/// Error ///

 Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function  'GetEnrollcontext': The specified procedure could not be found.

//DLL File Code//

SampleDLL.ProfileEnroll enrollcontext = new SampleDLL.ProfileEnroll();
enrollcontext.Url =" url";
enrollcontext.AuditIdType = SampleDLL.ProfileId;
enrollcontext.AuditId = "22222222 "; 
enrollcontext.ServerId = "server1";

/// Java Code ///

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Structure;
import dllExtract.DLLExtractTest.SampleDLL.Enrollcontext;


public class SampleDLLExtract {

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

        public static class Enrollcontext extends Structure { 

            public String auditId;
            public String serverId;
        }
            void GetEnrollcontext(Enrollcontext ec);                     // void ();
    }
    public static void main(String[] args) {
        SampleDLL sdll = SampleDLL.INSTANCE;
        SampleDLL.Enrollcontext enrollContext = new SampleDLL.Enrollcontext();
        sdll.GetEnrollcontext(enrollContext);

        System.out.println(sdll.toString(sdll.GetEnrollcontext(enrollContext))); 
    }
}

解决方案

in fact there is a solution for you to use C#, VB.NET or F# code via JNA in Java (and nothing else)! and it is also very easy to use: https://www.nuget.org/packages/UnmanagedExports

with this package all you need to do is, add [RGiesecke.DllExport.DllExport] to your methods like that:

C# .dll Project:

[RGiesecke.DllExport.DllExport]
public static String yourFunction(String yourParameter)
{
    return "CSharp String";
}

Java Project:

public interface jna extends Library {
    jna INSTANCE = (jna) Native.loadLibrary("yourCSharpProject.dll", jna.class);
public String yourFunction(String yourParameter);
}

use it in the code:

System.out.println(jna.INSTANCE.yourFunction("nothingImportant"));

Viola!

As already mentioned it works very easy, but this solution has some limitations:

only available for simple datatypes as parameter & return values no MethodOverloading available. yourFunction(String yourParameter) and yourFunction(String yourParameter, String yourSecondParameter) does not work! you have to name them differently Use arrays as parameter or return values. (JNA offers StringArray, but I am not able to use them in C#) (maybe there is a solution, but I couldn't come up with one so far!) if you export a method you can't call it internally in your C# code (simple to bypass that by the following:

.

[RGiesecke.DllExport.DllExport]
public static Boolean externalAvailable(String yourParameter)
{
    return yourInternalFunction(yourParameter);
}

With C# it works great, with VB.NET and F# I have no experience. hope this helps!