Linux 中的应用程序以以下两种方式之一链接到外部函数:要么在构建时与静态库( lib*.a ) 静态地链接,并且将库代码包含在该应用程序的可执行文件里;要么在运行时与共
享库( lib*.so ) 动态地链接。通过动态链接装入器,将动态库映射进应用程序的可执行内存中。在启动应用程序之前,动态链接装入器将所需的共享目标库映射到应用程序的
内存,或者使用系统共享的目标并为应用程序解析所需的外部引用。现在应用程序就可以运行了。
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 <jni.h>
#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 <stdio.h>
#include <dlfcn.h>
#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 <stdio.h>
void sayHi(char str[])
{
printf("hi!.... %s \n",str);
}
----------------------------------------------------------
test.c (适用于第二种情况)
#include <stdio.h>
#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
分享到:
相关推荐
Jni中执行ndk-build,编译第三方静态库(.a)和动态库(.so)的Android.mk文件写法,这是Jni测试引用第三方静态库和动态库demo
Java JNI调用动态库(Linux、Windows)的实现步骤
LINUX调用JNI动态库.txt LINUX调用JNI动态库.txt
jni学习例子 在linux下java调用so执行成功 java类型转成c类型 jstring 转char 相应的.so跟c跟.h跟点lib*.so都有,可以直接运行的
VS2015 Android JNI 静态库 动态库 APK 本地调试DEMO 自己摸索出来的,10分绝对不高.摆脱Android Studio摆脱Eclipse.摆脱VisualGDB 祝君工作愉悦
Java通过JNI调用DLL动态库,亲测试编写
jni调用C++动态库,jna调用C++动态库,eclipse maven project
在linux下,java调用c语言编译的*.so动态链接库的小例子.是一个简单计算器的例子.在java中传操作数和操作符,由C来计算,把结果传过来给java.
此程序在eclipse环境下可直接运行,希望可以帮到要用jni写串口的人
jni动态加载方式示例
springboot+jna/jni调用动态so/dll库
一步步说明在 Linux 平台下如何实现本地共享库与 Java 协同工作
教你如何生成.h文件,使用window通过NDK编译出.so文件,如何通过JNI调用so文件
Android 4.4.2 动态添加JNI库方法记录 (二 app应用层)配套的源码,需要的可以下载,绝对值得参考。
一般来说,JNI有点复杂。但是,如果你仅仅单向调用--从Java调用本地代码,并且仅使用基本型进行通讯--事情还是很简单的。本文介绍了在Java中声明JNI方法,给出了在Java应用程序中使用JNI来监视CPU的实例。
根据ffmpeg.wps操作生成静态文件。...根据hello-jni.zip文件生成动态库。内附成功生成的动态库,为经过none优化的解码h264的so文件。 ndk版本:android-ndk-r8-linux-x86 ffmpeg版本:ffmpeg-0.11.3
一个简单的jni demo,意在学习如何在Android Studio中引入jni程序。
记得是刚毕业时研究的JNI技术,希望帮到大家
基于老罗的《Android内核源代码情景分析》第二章freg实例,使用NDK编译jni层从而调用驱动程序,能大大缩短项目开发周期。
内含JNI的源码和动态库,其他的我也不知道该怎么说诶