保证java工程所在的系统上有java环境,编译生成动态链接库的系统上有c/c++环境。
1.编写java程序,生成.h文件,
package com.test;
public class LineConvert {
static {
System.loadLibrary("linenodef"); //动态链接库名为liblinenodef.so
}
public static native int load_cable(String fileName);
public static native String HWToname(byte[] data);
public static void main(String[] args) {
load_cable("123");
byte[] data = new byte[16];
for (int i = 0; i < 16; i++) {
data[i] = (byte)i;
}
String line = HWToname(data);
System.out.println("line " + line);
}
}
}
2.回到包的最高目录下(即工程的src目录下),编译java程序。
javac com/test/LineConvert.java
(生成LineConvert.class,运行一下该类也可编译生成class文件)
然后继续编译生成头文件(给c/c++程序用)
javah -jni -classpath . com.test.LineConvert
生成了com_test_LineConvert.h ,并复制到要编写 c/c++程序的路径
3.新建一个linenodef.cpp文件,编写c++库,把com_test_LineConvert.h 中的函数名复制到linenodef.cpp文件中,函数名不要修改,函数下面添加自己的内容即可。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "com_test_LineConvert.h"
JNIEXPORT jint JNICALL Java_com_test_LineConvert_load_1cable(JNIEnv *, jclass, jstring);
JNIEXPORT jstring JNICALL Java_com_test_LineConvert_HWToname(JNIEnv *, jclass, jbyteArray);
JNIEXPORT jint JNICALL Java_com_test_LineConvert_load_1cable(JNIEnv *env, jclass jc, jstring js)
{
printf("execute..... load_cable \n");
return 0;
}
JNIEXPORT jstring JNICALL Java_com_test_LineConvert_HWToname(JNIEnv * env, jclass jc, jbyteArray arr)
{
printf("execute..... HWToname \n");
char matrix[128];
int i;
for (i=0; i<128; i++)
matrix[i] = i;
return (env)->NewStringUTF(matrix);
}
4.编译生成so动态链接库,并将.so文件置于/usr/lib/目录下。
g++ -I /yuantek/jdk/include/ -I /yuantek/jdk/include/linux -o liblinenodef.so linenodef.cpp -fPIC -shared
-I后面是jdk、jni的路径,包含jni.h、jni_md.h,
-o后面为生成的动态链接库的名字,以lib开头、.so结尾,并与java程序中库名相对应
-fPIC:表示编译为位置独立(地址无关)的代码,不加此选项时,编译后的代码为位置相关的,动态载入时,通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
-shared:指定生成动态链接库
(c语言使用gcc编译,c++使用g++编译)
生成库之后ldd一下,ldd liblinenodef.so(看一下是否有关联其他库,如果有关联说明生成库没有问题)。
5.运行java程序看一下是否能进入so库中的函数,输出如下。
execute..... load_cable
execute..... HWToname