【问题标题】:I want to learn how to do what JNA does by writing my own JNI code我想通过编写自己的 JNI 代码来学习如何做 JNA 的工作
【发布时间】:2015-07-22 02:14:13
【问题描述】:

我是新手,我正在测试 JNA jar 库 jna-4.1.0.jarjna-platform-4.1.0.jar

我正在使用 Kernel32、User32、WinBase、WinDef、WinN 和 WinUser dll 测试性能。

但是,现在我不想使用 JNA(我知道更好更容易)我想使用 JNI(太难了)代替(也许我逆流而上)!!!

我想摆脱对外部 jar Java 文件的依赖

问题:什么对象可以用纯Java对象代替JNA对象?

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.Pointer;
import com.sun.jna.Union;
import com.sun.jna.NativeLong;
import com.sun.jna.ptr.IntByReference;

问题:我有一个使用 JNA 进行测试的代码,但我需要知道如何使用纯 Java 翻译这个结构?

例如SYSTEM_INFO structure

public static class SYSTEM_INFO extends Structure {
  public static class ByReference extends SYSTEM_INFO
  implements Structure.ByReference { }
  public static class UNION extends Union {
    public static class ByReference extends UNION
    implements Structure.ByReference { }

    public static class IntStruct extends Structure {
      public static class ByValue extends IntStruct 
      implements Structure.ByValue {}
      public short wProcessorArchitecture;
      public short  wReserved;
    }
    public int dwOemId;
    public IntStruct s;
  }
  int dwPageSize;
  Pointer lpMinimumApplicationAddress;
  Pointer lpMaximumApplicationAddress;
  NativeLong  dwActiveProcessorMask;
  int dwNumberOfProcessors;
  int dwProcessorType;
  int dwAllocationGranularity;
  short wProcessorLevel;
  short wProcessorRevision;
}

其他结构OSVERSIONINFOEX structure

typedef struct _OSVERSIONINFOEX {
  DWORD dwOSVersionInfoSize;
  DWORD dwMajorVersion;
  DWORD dwMinorVersion;
  DWORD dwBuildNumber;
  DWORD dwPlatformId;
  TCHAR szCSDVersion[128];
  WORD  wServicePackMajor;
  WORD  wServicePackMinor;
  WORD  wSuiteMask;
  BYTE  wProductType;
  BYTE  wReserved;
} OSVERSIONINFOEX, *POSVERSIONINFOEX, *LPOSVERSIONINFOEX;

也许这是最简单的部分:

  public interface Advapi32 extends Library {
    Advapi32 INSTANCE = (Advapi32)Native.loadLibrary("advapi32", Advapi32.class);
    boolean GetUserNameA(byte[] name, IntByReference intRef);
  }

PD我需要一个真正的教程如何使用JNI调用DLL函数(不是Hello world),使用指针和数据结构等等......

对不起,如果我输了... 谢谢!

【问题讨论】:

  • 您可能想解释一下 “我想摆脱对外部 jar Java 文件的依赖”的意思,因为手动编码 JNI 可能不是您唯一的选择.
  • 也许,你有理由,我想深入了解JNI,(我不了解JNI)

标签: java windows dll java-native-interface jna


【解决方案1】:

1) 获取所有使用基于 JNA 的 Library 接口的代码,并在 C 中重写它,将其编译为 DLL。

2) 在 JNI 中创建一个 API,以允许 Java 与您的新 C 代码对话(可能比您正在使用的完整 win32 API 小一些)

3) 编写代码以将本机结构转换为 Java 对象或原语。

没有从本机结构到 Java 对象的“神奇”转换,尽管您可以考虑 SWIG,它可能会为您生成代码来执行此操作。还有一个例子here

编辑

如果您想真正学习 JNI,那么从一些简单的功能开始,然后再转向更复杂的功能,一次一个。 JNA 的单元测试可以为您提供一些关于您可能在 Java 和本机之间传递的数据范围的指示。它自己的原生库 jnidispatch 几乎涵盖了您可能以一般方式进行的所有交互。

  • 函数返回类型
  • 函数参数
  • 复杂的数据映射(struct/Structure
  • 函数指针 (Callback) - 回调 Java 的本机代码

当然,JNA 的相当一部分与动态和自动确定如何将 Java 位转换为本机位有关,您可以在手动编写 JNI 代码时避免这种情况,因为您可以显式地编写任何 C 代码.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-01
    • 1970-01-01
    • 2020-03-01
    • 2015-01-31
    • 2012-11-27
    • 2018-06-04
    • 1970-01-01
    相关资源
    最近更新 更多