【问题标题】:Call DLL from Java using JNA使用 JNA 从 Java 调用 DLL
【发布时间】:2014-05-06 21:52:16
【问题描述】:

我不熟悉使用 JNA 从 Java 访问 DLL。我需要从 DLL 中的类访问方法(用 .net 编写)。形成下面的这个示例 DLL,我正在尝试获取 AuditID 和服务器 ID。我在运行代码时以以下错误结束。非常感谢任何指导。

/// 错误 ///

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

//DLL文件代码//

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

/// 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))); 
    }
}

【问题讨论】:

  • 经过大量研究,确认无法使用JNA框架调用VB或C Sharp编写的DLL文件。 JNA 正在使用系统 DLL,但不适用于第三方 DLL。

标签: java .net dll jna


【解决方案1】:

事实上,您可以通过 Java 中的 JNA 使用 C#、VB.NET 或 F# 代码(仅此而已)!而且它也很容易使用: https://www.nuget.org/packages/UnmanagedExports

使用这个包,您只需将 [RGiesecke.DllExport.DllExport] 添加到您的方法中,如下所示:

C# .dll 项目:

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

Java 项目:

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

在代码中使用它:

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

维奥拉!

正如已经提到的,它工作起来非常简单,但是这个解决方案有一些限制:

  • 仅适用于作为参数和返回值的简单数据类型
  • 没有可用的方法重载。 yourFunction(String yourParameter) 和 yourFunction(String yourParameter, String yourSecondParameter) 不起作用!您必须以不同的方式命名它们
  • 使用数组作为参数或返回值。 (JNA 提供了 StringArray,但我无法在 C# 中使用它们)(也许有一个解决方案,但我至今想不出一个!)
  • 如果你导出一个方法,你不能在你的 C# 代码内部调用它(简单地通过以下方式绕过它:

.

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

使用 C# 效果很好,使用 VB.NET 和 F# 我没有经验。 希望这会有所帮助!

【讨论】:

  • 感谢您的详细解答。我浏览了 jn14net (jni4net.sourceforge.net) 文档并想尝试一下。你有什么建议吗?
  • 对 jni4net 的建议?不是一般的,对不起。基本示例看起来不错,但不知道如何将它们与其他类一起使用,然后是 c# 类,它们已经包含在 jni4net.version.jar 中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-10
  • 1970-01-01
  • 1970-01-01
  • 2015-11-23
  • 1970-01-01
相关资源
最近更新 更多