void *dlopen( const char *file, int mode );//将共享目标文件打开并且映射到内存中,并且返回句柄
void *dlsym( void *restrict handle, const char *restrict name );//回一个指向被请求入口点的指针
char *dlerror();//返回 NULL 或者一个指向描述最近错误的 ASCII 字符串的指针
char *dlclose( void *handle );//关闭句柄并且取消共享目标文件的映射
例子说明:在test.c中调用sayHi();
文件清单
Test.java
class Test {
public native void sayHi();
public static void main(String[] args) {
Test test=new Test();
test.sayHi();
}
static {
System.loadLibrary("test");
}
}
Test.h
#include
#ifndef _Included_Test
#define _Included_Test
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL Java_Test_sayHi
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
test.c (适用于第一种情况)
#include
#include
#include "Test.h"
void *FunctionLib; /* Handle to shared lib file */
int (*Function)(); /* Pointer to loaded routine */
const char *dlError; /* Pointer to error string */
JNIEXPORT void JNICALL Java_Test_sayHi(JNIEnv* env, jobject obj)
{
int rc; /* return codes */
char HelloMessage[] = "HeLlO WoRlD\n";
FunctionLib = dlopen("/yijia/libtest2.so",RTLD_LAZY);
dlError = dlerror();
printf("1 \n", dlError);
if( dlError ) exit(1);
Function = dlsym( FunctionLib, "sayHi");
dlError = dlerror();
printf("2\n", dlError);
if( dlError ) exit(1);
rc = (*Function)( HelloMessage );
printf("3 \n", dlError);
rc = dlclose(FunctionLib);
dlError = dlerror();
printf("4 \n",dlError);
if( rc ) exit(1);
rc = dlclose(FunctionLib);
dlError = dlerror();
printf("5 \n",dlError);
if( rc ) exit(1);
}
test2.c
#include
void sayHi(char str[])
{
printf("hi!.... %s \n",str);
}
----------------------------------------------------------
test.c (适用于第二种情况)
#include
#include "Test.h"
JNIEXPORT void JNICALL Java_Test_sayHi(JNIEnv* env, jobject obj)
{
//sayHi("hello!\n");
//jni函数实现调用sayHi(),继续学习jni的函数
}
第一种情况:加载动态库*.so
step1.新建java文件,编译,生成头文件
javac Test.java
javah Test
step2.新建test.c文件,生成动态库.so文件
生成libtest2.so
gcc -c -fpic test2.c
gcc -shared -o libtest2.so test2.o
生成libtest.so
gcc -c -fpic test.c
gcc -shared -lc -o libtest.so test.o -ldl
-ldl选项,表示生成的对象模块需要使用共享库
step3.运行java文件
java -Djava.library.path=. Test
./Test
第二种情况:加载静态库*.a
step1.新建java文件,编译,生成头文件
javac Test.java
javah Test
step2.新建test2.c文件,生成静态库.a文件
生成libtest2.a
gcc -c test2.c -o test2.o //编译成目标文件
ar rs libtest2.a test2.o //打包成一个静态库
参数r表示将后面的文件列表添加到文件包,如果文件包不存在就创建它,如果文件包中已有同名文件就替换成新的。
参数s是专用于生成静态库的,表示为静态库创建索引,这个索引被链接器使用。
生成libtest.a
gcc -c test.c -o test.o //编译成目标文件
ar rs libtest.a test.o //打包成一个静态库
step3.运行java文件
java -Djava.library.path=. Test
./Test