简体   繁体   English

使用JNA从Java调用DLL

[英]Call DLL from Java using JNA

I am new to accessing DLLs from Java using JNA. 我是第一次使用JNA从Java访问DLL。 I need to access methods from a class within a DLL(written in .net). 我需要从DLL(用.net编写)中的类访问方法。 Form this sample DLL below, I am trying to get AuditID and Server ID. 从下面的此示例DLL中,我尝试获取AuditID和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// // DLL文件代码//

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

/// Java Code /// /// Java代码///

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)! 实际上,有一种解决方案可以让您通过Java中的JNA使用C#,VB.NET或F#代码(别无其他)! and it is also very easy to use: https://www.nuget.org/packages/UnmanagedExports 而且它也非常易于使用: https : //www.nuget.org/packages/UnmanagedExports

with this package all you need to do is, add [RGiesecke.DllExport.DllExport] to your methods like that: 使用此软件包,您需要做的就是将[RGiesecke.DllExport.DllExport]添加到您的方法中,如下所示:

C# .dll Project: C#.dll项目:

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

Java Project: Java专案:

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. 没有可用的MethodOverloading。 yourFunction(String yourParameter) and yourFunction(String yourParameter, String yourSecondParameter) does not work! yourFunction(String yourParameter)和yourFunction(String yourParameter,字符串yourSecondParameter)不起作用! 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!) (JNA提供StringArray,但我无法在C#中使用它们)(也许有解决方案,但到目前为止我还没有提出!)
  • if you export a method you can't call it internally in your C# code (simple to bypass that by the following: 如果导出方法,则无法在C#代码中内部调用该方法(通过以下操作可以轻松绕过该方法:

.

[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. 使用C#可以很好地工作,而使用VB.NET和F#则没有经验。 hope this helps! 希望这可以帮助!

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

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