文档章节

Java(Native)

赵-猛
 赵-猛
发布于 2017/08/08 21:43
字数 843
阅读 13
收藏 0

jni
   java call c/c++ implementation api
   c/c++ call java/jvm api

jnative (便于利用已经存在的native库))
   java call existing dll/so api

jna(便于集成打包发布, best)
   java call existing dll/so api

swig 
   java/python call c/c++ implementation api

javacpp


jni(JVM + javac + GCC)
1.atom ./com/intellif/sample/jni/HelloWorld.java

package com.intellif.sample.jni;
public class HelloWorld {
   public native int add(int a, int b);
}

 atom ./com/intellif/sample/jni/HelloWorldApp.java

package com.intellif.sample.jni;
public class HelloWorldApp {
   static {
       System.loadLibrary("hw");
   }

   public static void main(String[] args) {
       HelloWorld wh = new HelloWorld();
       int sum = wh.add(1, 2);
       System.out.println(sum);
   }
}

2.javac ./com/intellif/sample/jni/HelloWorld.java ./com/intellif/sample/jni/HelloWorldApp.java

3.javah -jni com.intellif.sample.jni.HelloWorld

4.cat com_intellif_sample_jni_HelloWorld.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_intellif_sample_jni_HelloWorld */

#ifndef _Included_com_intellif_sample_jni_HelloWorld
#define _Included_com_intellif_sample_jni_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_intellif_sample_jni_HelloWorld
 * Method:    add
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_intellif_sample_jni_HelloWorld_add
  (JNIEnv *, jobject, jint, jint);

#ifdef __cplusplus
}
#endif
#endif


5.atom com_intellif_sample_jni_HelloWorld.cpp

#include <jni.h>
#include "com_intellif_sample_jni_HelloWorld.h"
#include <stdio.h>
JNIEXPORT jint JNICALL Java_com_intellif_sample_jni_HelloWorld_add
  (JNIEnv *env, jobject obj, jint a, jint b)
{
    printf("Hello world! \n");
    jint c = a + b;
    return c;
}

6.g++ -shared -fPIC -I $JAVA_HOME/include -I JAVA_HOME/include/linux -o hw.so com_intellif_sample_jni_HelloWorld.cpp

  readelf -s libhw.so

7.java -Djava.library.path=. com.intellif.sample.jni.HelloWorldApp

 


jnative(便于利用已经存在的native库)
JVM + libJNativeCpp.so + JNative.jar + javac + libxxxx.so/xxxx.dll

1.atom JNative_HelloWorld.h

#ifndef JNative_HelloWorld
#define JNative_HelloWorld

extern "C" int add(int a, int b);

#endif

  atom JNative_HelloWorld.cpp

#include "JNative_HelloWorld.h"
#include <stdio.h>

int add(int a, int b) {
    printf("Hello world! \n");
    int c = a + b;
    return c;
}

2. g++ -shared -fPIC -o libjnativehw.so JNative_HelloWorld.h JNative_HelloWorld.cpp -ldl
   readelf -s libjnativehw.so

makefile

default: build

clean:
	-rm ../src/main/resources/libjnativehw.so
	
build: clean
	g++ -shared -fPIC -o libjnativehw.so JNative_HelloWorld.h JNative_HelloWorld.cpp -ldl
	mv libjnativehw.so ../src/main/resources/libjnativehw.so

3.atom ./com/intellif/sample/jnative/HelloWorldApp.java

package com.intellif.sample.jnative;

import org.xvolks.jnative.JNative;
import org.xvolks.jnative.Type;
import org.xvolks.jnative.exceptions.NativeException;

public class HelloWorldApp {
    public static int nativeAdd(int a, int b) throws NativeException, IllegalAccessException {
        JNative n = null;
        n = new JNative("libxxxx.so", "add");
        n.setRetVal(Type.INT);
        n.setParameter(0, a);
        n.setParameter(1, b);
        n.invoke();
        System.out.println("返回: " + n.getRetVal());
        return Integer.parseInt(n.getRetVal());
    }
    
    public static void main(String[] args) {
        try {
            nativeAdd(1, 2);
        } catch (NativeException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

4.javac ./com/intellif/sample/jnative/HelloWorldApp.java

5.java -cp ./JNative.jar -Djava.library.path=. com.intellif.sample.jnative.HelloWorldApp

 

jna(便于打包)
JVM + jna.jar + javac + libxxxx.so/xxxx.dll
1.atom JNA_HelloWorld.h

#ifndef JNA_HelloWorld
#define JNA_HelloWorld

extern "C" int add(int a, int b);

#endif

  atom JNA_HelloWorld.cpp

#include "JNA_HelloWorld.h"
#include <stdio.h>

int add(int a, int b) {
    printf("Hello world! \n");
    int c = a + b;
    return c;
}

2. g++ -shared -fPIC -o libjnahw.so JNA_HelloWorld.h JNA_HelloWorld.cpp -ldl
   readelf -s libjnahw.so

makefile

default: build

clean:
	-rm ../src/main/resources/libjnahw.so
	
build: clean
	g++ -shared -fPIC -o libjnahw.so JNA_HelloWorld.h JNA_HelloWorld.cpp -ldl
	mv libjnahw.so ../src/main/resources/libjnahw.so

3.atom  ./com/intellif/sample/jna/HelloWorld.java(libjnahw.so必须在classpath里)

package com.intellif.sample.jna;
public interface HelloWorld extends Library {
    int add(int a, int b);
}

#atom ./com/intellif/sample/jna/HelloWorldApp.java
package com.intellif.sample.jna;
public class HelloWorldApp {
	static {
		String property = System.getProperty("java.library.path");
		StringTokenizer parser = new StringTokenizer(property, ":");
		System.out.println("native library path:");
		while (parser.hasMoreTokens()) {
			System.out.println(parser.nextToken());
		}
	}

	static {
		URLClassLoader loader = (URLClassLoader) ClassLoader.getSystemClassLoader();
		URL[] liburls = loader.getURLs();
		System.out.println("class url path:");
		for (URL url : liburls) {
			System.out.println(url);
		}
	}

  public static void main(String[] args) {
     HelloWorld hw = Native.loadLibrary("jnahw", HelloWorld.class);
     int sum = hw.add(1,2);
     System.out.println(sum);
  }
}  

4.javac -cp $HOME/.m2/repository/net/java/dev/jna/jna/4.4.0/jna-4.4.0.jar ./com/intellif/sample/jna/HelloWorld.java ./com/intellif/sample/jna/HelloWorldApp.java

5.java -cp $HOME/.m2/repository/net/java/dev/jna/jna/4.4.0/jna-4.4.0.jar:. com.intellif.sample.jna.HelloWorldApp

 

C type -> jna type

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 => java_int

C_struct拷贝参数 => java Structure.ByValue(C_struct => java Structure,注意字段为public)
C_struct指针 => java XStructure.ByReference
C_struct引用 => java XStructure.ByReference
C_struct指针(实际上是数组) => java XStructure[]

C_basictype拷贝参数 => java_basictype(见上表)
C_* => Pointer, 基本类型也可以使用基本类型的XXXByReference
C_& => Pointer, 基本类型也可以使用基本类型的XXXByReference
C_*(实际上是数组) => java XStructure[]

C_** => PointerByReference
C_*& => 属于c++范畴,不支持

 

© 著作权归作者所有

上一篇: SpringBoot(Properties)
下一篇: Search(Solr)
赵-猛
粉丝 6
博文 820
码字总数 500010
作品 0
深圳
技术主管
私信 提问
在 JNI 编程中避免内存泄漏

此文转自 IBM developerWorks JNI 编程简介 JNI,Java Native Interface,是 native code 的编程接口。JNI 使 Java 代码程序可以与 native code 交互——在 Java 程序中调用 native code;在...

IBMdW
2011/04/26
985
1
android jni回调 转自http://android.wooyd.org/JNIExa...

Important notice<注意> The instructions in these document are applicable to older Android firmwares. Starting with firmware version 1.5 the Android NDK has been released, which......

貌似高手
2012/07/06
394
1
Java Run-Time Data Areas(Java运行时数据区/内存分配)

Java运行时数据区(内存分配) 本文转载官网 更多相关内容可查看官网 中文翻译可参考 2.5. Run-Time Data Areas The Java Virtual Machine defines various run-time data areas that are use...

lichuangnk
2018/08/19
17
0
android app中使用JNI

JNI提供了一种机制,使得在Java 代码中可以使用 C/C++ 的本地层代码,这种使用主要是指在 Java 代码中调用 C/C++ 代码。这种机制为我们开启了一扇门,一扇将Java 代码与广阔的 C/C++ 本地层连...

WolfCS
2013/03/02
4.2K
1
JNI 之二 :java & c/c++ 相互通信及调用

JNI是Java Native Interface的缩写,JNI是一种机制,有了它就可以在java程序中调用其他native代码,或者使native代码调用java层的代码。也就是说,有了JNI我们可以使Android项目中,java层与...

LiSteven
2013/04/01
276
0

没有更多内容

加载失败,请刷新页面

加载更多

只需一步,在Spring Boot中统一Restful API返回值格式与统一处理异常

统一返回值 在前后端分离大行其道的今天,有一个统一的返回值格式不仅能使我们的接口看起来更漂亮,而且还可以使前端可以统一处理很多东西,避免很多问题的产生。 比较通用的返回值格式如下:...

晓月寒丶
今天
59
0
区块链应用到供应链上的好处和实际案例

区块链可以解决供应链中的很多问题,例如记录以及追踪产品。那么使用区块链应用到各产品供应链上到底有什么好处?猎头悬赏平台解优人才网小编给大家做个简单的分享: 使用区块链的最突出的优...

猎头悬赏平台
今天
27
0
全世界到底有多少软件开发人员?

埃文斯数据公司(Evans Data Corporation) 2019 最新的统计数据(原文)显示,2018 年全球共有 2300 万软件开发人员,预计到 2019 年底这个数字将达到 2640万,到 2023 年达到 2770万。 而来自...

红薯
今天
61
0
Go 语言基础—— 通道(channel)

通过通信来共享内存(Java是通过共享内存来通信的) 定义 func service() string {time.Sleep(time.Millisecond * 50)return "Done"}func AsyncService() chan string {retCh := mak......

刘一草
今天
57
0
Apache Flink 零基础入门(一):基础概念解析

Apache Flink 的定义、架构及原理 Apache Flink 是一个分布式大数据处理引擎,可对有限数据流和无限数据流进行有状态或无状态的计算,能够部署在各种集群环境,对各种规模大小的数据进行快速...

Vincent-Duan
今天
59
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部