`
zhaohaolin
  • 浏览: 1016200 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

【JAVA实用工具】JNA-通过它调用C++的方法,比JNI方便很多访问网站需要代理,所以把它COPY出来备忘

 
阅读更多

How To Get Started Using JNA

Java Native Access (JNA) has a single component, jna.jar; the supporting native library (jnidispatch) is included in the jar file. JNA is capable of extracting and loading the native library on its own, so you don't need additional configuration. JNA falls back to extraction if the native library is not already installed on the local system somewhere accessible to System.loadLibrary (see information on library loading). The native library is also available in platform-specific jar files for use with Java Web Start.

  1. Download jna.jar from the download page.
  2. Compile and run this short example, which maps the printf function from the standard C library and calls it. Be sure to include jna.jar in the classpath:
    package com.sun.jna.examples; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.Platform; public class HelloWorld { // This is the standard, stable way of mapping, which supports extensive // customization and mapping of Java to native types. public interface CLibrary extends Library { CLibrary INSTANCE = (CLibrary) Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"), CLibrary.class); void printf(String format, Object... args); } public static void main(String[] args) { CLibrary.INSTANCE.printf("Hello, World\n"); for (int i=0;i < args.length;i++) { CLibrary.INSTANCE.printf("Argument %d: %s\n", i, args[i]); } } }
  3. Identify a native target library that you want to use. This can be any shared library with exported functions. Many examples of mappings for common system libraries may be found in the platform package.
  4. Make your target library available to your Java program. There are two ways to do this:
    • The preferred method is to set the jna.library.path system property to the path to your target library. This property is similar to java.library.path but only applies to libraries loaded by JNA.
    • Change the appropriate library access environment variable before launching the VM. This is PATH on Windows, LD_LIBRARY_PATH on Linux, and DYLD_LIBRARY_PATH on OSX.
  5. Declare a Java interface to hold the native library methods by extending the Library interface.

    Following is an example of mapping for the Windows kernel32 library.

    package com.sun.jna.examples.win32; import com.sun.jna.*; // kernel32.dll uses the __stdcall calling convention (check the function // declaration for "WINAPI" or "PASCAL"), so extend StdCallLibrary // Most C libraries will just extend com.sun.jna.Library, public interface Kernel32 extends StdCallLibrary { // Method declarations, constant and structure definitions go here }
  6. Within this interface, define an instance of the native library using the Native.loadLibrary(Class) method, providing the native library interface you defined in step (5).
    Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class); // Optional: wraps every call to the native library in a // synchronized block, limiting native calls to one at a time Kernel32 SYNC_INSTANCE = (Kernel32) Native.synchronizedLibrary(INSTANCE);

    The INSTANCE variable is for convenient reuse of a single instance of the library. Alternatively, you can load the library into a local variable so that it will be available for garbage collection when it goes out of scope. AMap of options may be provided as the third argument to loadLibrary to customize the library behavior; some of these options are explained in more detail below. The SYNC_INSTANCE is also optional; use it if you need to ensure that your native library has only one call to it at a time.
  7. Declare methods that mirror the functions in the target library by defining Java methods with the same name and argument types as the native function (refer to the basic mappings below or the detailed table of type mappings). You may also need to declare native structures to pass to your native functions. To do this, create a class within the interface definition that extends Structure and add public fields (which may include arrays or nested structures).
    public static class SYSTEMTIME extends Structure { public short wYear; public short wMonth; public short wDayOfWeek; public short wDay; public short wHour; public short wMinute; public short wSecond; public short wMilliseconds; } void GetSystemTime(SYSTEMTIME result);
  8. You can now invoke methods on the library instance just like any other Java class. For a more extensive example, see the WindowUtils and ShapedWindowDemo classes.
    Kernel32 lib = Kernel32.INSTANCE; SYSTEMTIME time = new SYSTEMTIME(); lib.GetSystemTime(time); System.out.println("Today's integer value is " + time.wDay);
  9. Alternatively, you may declare a class to hold your native methods, declare any number of methods with the "native" qualifier, and invoke Native.register(String) in the class static initializer with your library's name. See JNA direct mapping for an example.

     

If the C header files for your library are available, you can auto-generate a library mapping by using Olivier Chafik's excellent JNAerator utility. This is especially useful if your library uses long or complicated structures where translating by hand can be error-prone.

See the JavaDoc overview for more detailed information about JNA usage.

Top

Default Type Mappings

Java primitive types (and their object equivalents) map directly to the native C type of the same size.
Native Type Size Java Type Common Windows Types
char 8-bit integer byte BYTE, TCHAR
short 16-bit integer short WORD
wchar_t 16/32-bit character char TCHAR
int 32-bit integer int DWORD
int boolean value boolean BOOL
long 32/64-bit integer NativeLong LONG
long long 64-bit integer long __int64
float 32-bit FP float
double 64-bit FP double
char* C string String LPTCSTR
void* pointer Pointer LPVOID, HANDLE, LPXXX
Unsigned types use the same mappings as signed types. C enums are usually interchangeable with "int". A more comprehensive list of mappings may be found here.

Top

Using Pointers and Arrays

Primitive array arguments (including structs) are represented by their corresponding Java types. For example:
// Original C declarations void fill_buffer(int *buf, int len); void fill_buffer(int buf[], int len); // same thing with array syntax // Equivalent JNA mapping void fill_buffer(int[] buf, int len);

NOTE: if the parameter is to be used by the native function outside the scope of the function call, you must useMemory or an NIO Buffer. The memory provided by a Java primitive array will only be valid for use by the native code for the duration of the function call.

Arrays of C strings (the char* argv[] to the C main, for example), may be represented by String[] in Java code. JNA will pass an equivalent array with a NULL final element.

Top

Using Structures/Unions

When a function requires a pointer to a struct, a Java Structure should be used. If the struct is passed or returned by value, you need only make minor modifications to the parameter or return type class declaration.

Typically you define a public static class derived from Structure within your library interface definition. This allows the structure to share any options (like custom type mapping) defined for the library interface.

If a function requires an array of struct (allocated contiguously in memory), a Java Structure[] may be used. When passing in an array of Structure, it is not necessary to initialize the array elements (the function call will allocate, zero memory, and assign the elements for you). If you do need to initialize the array, you should use theStructure.toArray method to obtain an array of Structure elements contiguous in memory, which you can then initialize as needed.

Unions are generally interchangeable with Structures, but require that you indicate which union field is active with the setType method before it can be properly passed to a function call.

Top

Using By-reference Arguments

When a function accepts a pointer-to-type argument you can use one of the ByReference types to capture the returned value, or subclass your own. For example:
// Original C declaration void allocate_buffer(char **bufp, int* lenp); // Equivalent JNA mapping void allocate_buffer(PointerByReference bufp, IntByReference lenp); // Usage PointerByReference pref = new PointerByReference(); IntByReference iref = new IntByReference(); lib.allocate_buffer(pref, iref); Pointer p = pref.getValue(); byte[] buffer = p.getByteArray(0, iref.getValue());
Alternatively, you could use a Java array with a single element of the desired type, but the ByReferenceconvention better conveys the intent of the code.

The Pointer class provides a number of accessor methods in addition to getByteArray() which effectively function as a typecast onto the memory.

Type-safe pointers may be declared by deriving from the PointerType class.

Top

Customized Mapping from Java to Native (Types and Function Names)

The TypeMapper class and related interfaces provide for converting any Java type used as an argument, return value, or structure member to be converted to or from a native type. The example w32 API interfaces use a type mapper to convert Java boolean into the w32 BOOL type. A TypeMapper instance is passed as the value for the TYPE_MAPPER key in the options map passed to Native.loadLibrary.

Alternatively, user-defined types may implement the NativeMapped interface, which determines conversion to and from native types on a class-by-class basis.

You may also customize the mapping of Java method names to the corresponding native function name. TheStdCallFunctionMapper is one implementation which automatically generates stdcall-decorated function names from a Java interface method signature. The mapper should be passed as the value for theOPTION_FUNCTION_MAPPER key in the options map passed to the Native.loadLibrary call.

Refer to this table in the overview for a complete list of built-in type mappings.

Top

Callbacks/Closures (Function Pointers)

Callback declarations consist of a simple interface that extends the Callback interface and implements a callbackmethod (or defines a single method of arbitrary name). Callbacks are implemented by wrapping a Java object method in a little bit of C glue code. The simplest usage resembles using anonymous inner classes to register event listeners. Following is an example of callback usage:
// Original C declarations typedef void (*sig_t)(int); sig_t signal(sig_t); // Equivalent JNA mappings public interface CLibrary extends Library { int SIGUSR1 = 30; interface sig_t extends Callback { void invoke(int signal); } sig_t signal(int sig, sig_t fn); int raise(int sig); } ... CLibrary lib = (CLibrary)Native.loadLibrary("c", CLibrary.class); // WARNING: you must keep a reference to the callback object // until you deregister the callback; if the callback object // is garbage-collected, the native callback invocation will // probably crash. CLibrary.sig_t fn = new CLibrary.sig_t() { public void invoke(int sig) { System.out.println("signal " + sig + " was raised"); } }; CLibrary.sig_t old_handler = lib.signal(CLibrary.SIGUSR1, fn); lib.raise(CLibrary.SIGUSR1); ...
Here is a more involved example, using the w32 APIs to enumerate all native windows:
// Original C declarations typedef int (__stdcall *WNDENUMPROC)(void*,void*); int __stdcall EnumWindows(WNDENUMPROC,void*); // Equivalent JNA mappings public interface User32 extends StdCallLibrary { interface WNDENUMPROC extends StdCallCallback { boolean callback(Pointer hWnd, Pointer arg); } boolean EnumWindows(WNDENUMPROC lpEnumFunc, Pointer arg); } ... User32 user32 = User32.INSTANCE; user32.EnumWindows(new WNDENUMPROC() { int count; public boolean callback(Pointer hWnd, Pointer userData) { System.out.println("Found window " + hWnd + ", total " + ++count); return true; } }, null);
If your callback needs to live beyond the method invocation where it is used, make sure you keep a reference to it or the native code will call back to an empty stub after the callback object is garbage collected.

Proxy wrappers are automatically generated for function pointers found within structs initialized by native code. This facilitates calling those functions from Java.

Top

Invocation from Dynamically-Typed Languages

Languages such as Jython or JRuby may find it more convenient to access the NativeLibrary and Function classes directly rather than establishing a dedicated interface.

Here's a brief example of using JNA from JRuby:

require 'java' module Libc @@lib = com.sun.jna.NativeLibrary.getInstance("c") @@ptr_funcs = [ 'fopen', 'malloc', 'calloc' ] def self.method_missing(meth, *args) if @@ptr_funcs.include?(meth.to_s) @@lib.getFunction(meth.to_s).invokePointer(args.to_java) else @@lib.getFunction(meth.to_s).invokeInt(args.to_java) end end O_RDONLY = 0 O_WRONLY = 1 O_RDWR = 2 end Libc.puts("puts from libc") Libc.printf("Hello %s, from printf\n", "World") file = Libc.open("/dev/stdout", 1, Libc::O_WRONLY) n = Libc.write(file, "Test\n", 5) puts "Wrote #{n} bytes via Libc" path = "/dev/stdout" fp = Libc.fopen(path, "w+") Libc.fprintf(fp, "fprintf to %s via stdio\n", path) Libc.fflush(fp) Libc.fclose(fp)

Top

Platform Library

JNA includes platform.jar that has cross-platform mappings and mappings for a number of commonly used platform functions, including a large number of Win32 mappings as well as a set of utility classes that simplify native access. The code is tested and the utility interfaces ensure that native memory management is taken care of correctly.

Before you map your own functions, check the platform package documentation for an already mapped one.

Platform-specific structures are mapped by header. For example, ShlObj.h structures can be found incom.sun.jna.platform.win32.ShlObj. Platform functions are mapped by library. For example, Advapi32.dllfunctions can be found in com.sun.jna.platform.win32.Advapi32. Simplified interfaces (wrappers) forAdvapi32.dll functions can be found in com.sun.jna.platform.win32.Advapi32Util.

Cross-platform functions and structures are implemented in com.sun.jna.platform. These currently include the following.

  • FileMonitor: a cross-platform file system watcher
  • FileUtils: a cross-platform set of file-related functions, such as move to the recycle bin
  • KeyboardUtils: a cross-platform set of keyboard functions, such as finding out whether a key is pressed
  • WindowUtils: a cross-platform set of window functions, providing non-rectangular shaped and transparent windows

分享到:
评论

相关推荐

    java jna 调用pytorch c++模型推理

    JNA(Java Native Access)是Java平台上的一个库,它允许Java代码直接调用本机库(如C++编写的库),而无需编写JNI(Java Native Interface)代码。这种方式可以方便地将高性能的C++库集成到Java应用程序中。 在...

    jna-4.5.1 , jna-4.5.1-sources , jna-platform-4.5.1 jar包

    JNA提供一组Java工具类用于在运行期动态访问系统本地库(native library:如Window的dll)而不需要编写任何Native/JNI代码。开发人员只要在一个java接口中描述目标native library的函数与结构,JNA将自动实现Java...

    jni-jna-web.zip

    在"jni-jna-web"项目中,可能包含了使用JNI编写的本地方法,这些方法可能是为了提高特定操作的性能,或者调用了无法用纯Java实现的库函数。 JNI的关键步骤包括: 1. 定义本地方法:在Java类中声明native方法,不...

    JNA调用C++动态库,传入二维数组,通过C++返回二维数组,java调用C++完整案例

    Java Native Access (JNA) 是一个非常实用的框架,它允许Java程序直接调用本地(Native)代码,无需编写JNI(Java Native Interface)代码。本案例将详细介绍如何使用JNA来调用C++动态库,特别是处理二维数组的输入和...

    jna-5.6.0.jar、jna-platform-5.6.0.jar

    总结来说,"jna-5.6.0.jar"和"jna-platform-5.6.0.jar"是Java开发者调用C++ DLL文件的关键工具,它们提供了一个高效、便捷的桥梁,使得Java程序能够充分利用本地系统的功能,而无需深入JNI的复杂性。这两个库不仅...

    jna调用C++dll

    Java Native Access(JNA)是Java平台上的一个开源库,它允许Java代码直接调用操作系统提供的原生API,而无需编写JNI(Java Native Interface)代码。这个技术在处理跨平台的系统集成、底层硬件访问或者利用已有的C/...

    JNA 调用dll jna调用 c++

    Java Native Access(JNA)是Java平台上的一个开源库,它允许Java代码直接调用操作系统提供的原生函数,而无需编写C语言的中间接口(JNI)。JNA通过映射Java方法到本地库中的函数,实现了Java与C/C++等本地代码的...

    JNA-5.7.0 jna-platform-5.7.0

    总的来说,JNA-5.7.0和jna-platform-5.7.0是Java开发中非常实用的工具,它们极大地降低了与本地系统交互的复杂性,使得Java开发者可以更加专注于业务逻辑,而不是底层的系统调用实现。通过学习和掌握JNA的使用,...

    jna-3.3.0 & jna-3.3.0-platform

    综上所述,`jna-3.3.0.jar`和`jna-3.3.0-platform.jar`是Java开发中调用本地资源的重要工具,它们提供了一种简便的方式让Java程序能够直接利用操作系统的能力,而无需深入学习C/C++编程。通过理解JNA的工作原理和...

    jna-4.2.2.jar jna-platform-4.2.2.jar

    标题中的"jna-4.2.2.jar"和"jna-platform-4.2.2.jar"是Java Native Access (JNA)框架的两个关键组件的版本号为4.2.2的JAR文件。JNA是Java平台上的一个开源库,它允许Java代码直接调用操作系统提供的原生函数,而无需...

    java使用(jna)调用c/c++第三方动态库 dll文件 所用jar包

    Java 使用 JNA(Java Native Access)调用C/C++编写的第三方动态库(DLL文件)是一种常见的技术,它允许Java程序直接与本地操作系统接口交互,而无需编写JNI(Java Native Interface)代码。JNA 提供了一种相对简洁...

    Android通过JNA调用C,C++方法

    总结,Android通过JNA调用C/C++方法是一个高效且方便的方式,它减少了JNI的繁琐步骤,使Java开发者能更容易地利用C/C++代码。不过,在追求性能或处理复杂数据结构时,可能需要考虑使用JNI。正确理解和使用JNA,可以...

    jni调用C++动态库,jna调用C++动态库

    在Java世界中,有时我们需要利用Java Native Interface (JNI) 和 Java Native Access (JNA) 这两种技术来调用C++编写的动态链接库(DLL或SO文件),以实现Java程序与底层系统的交互。这两者都是Java平台上的关键组件,...

    使用JNA替代JNI调用DLL,并解决内存溢出问题

    ### 使用JNA替代JNI调用DLL,并解决内存溢出问题 #### 问题背景 在项目的开发过程中,常常遇到需要处理二进制流数据并对其进行解析处理的情况。这种情况下,如果上层应用平台采用的是Java开发,而底层算法或数据...

    jna_jni之java调用C

    使用JNI需要编写本地方法,这些方法在Java类中声明为native,并通过`javah`工具生成对应的C/C++头文件。然后,开发者需要实现这个头文件中的方法,最后将实现的库与Java应用一起打包。尽管JNI提供了极大的灵活性,但...

    springboot+jna/jni调用动态so/dll库

    在这种情况下,"springboot+jna/jni调用动态so/dll库"是一个重要的主题,它涉及到Spring Boot应用如何利用Java Native Interface (JNI) 和 Java Native Access (JNA) 这两种技术来调用操作系统级别的动态链接库(.so...

    Java调用C++类库--JNI

    Java调用C++类库是跨语言编程中的一个重要应用场景,主要通过Java Native Interface(JNI)来实现。JNI是Java平台标准的一部分,它允许Java代码和其他语言写的代码进行交互。这在需要利用C++的高性能计算、系统级...

    jna-platform-4.1.0-API文档-中文版.zip

    赠送jar包:jna-platform-4.1.0.jar; 赠送原API文档:jna-platform-4.1.0-javadoc.jar; 赠送源代码:jna-platform-4.1.0-sources.jar; 赠送Maven依赖信息文件:jna-platform-4.1.0.pom; 包含翻译后的API文档:...

    JNA文件包-java调用c++

    Java Native Access(JNA)是Java平台上的一个开源库,它允许Java代码直接与本地操作系统API交互,无需编写C代码或使用JNI(Java Native Interface)。这个文件包专注于讲解如何使用JNA来调用C++函数,这对于那些...

    java-jna-4.2.1.jar

    Java Native Access(JNA)是Java开发中的一个重要工具,它为Java程序员提供了直接与操作系统本地库交互的能力,而无需编写JNI(Java Native Interface)代码。这个工具极大地简化了Java应用程序与底层系统功能的...

Global site tag (gtag.js) - Google Analytics