Chinaunix首页 | 论坛 | 博客
  • 博客访问: 461900
  • 博文数量: 191
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 172
  • 用 户 组: 普通用户
  • 注册时间: 2013-10-31 14:35
个人简介

没有时间把一件事情做好,却有时间把一件事情反复做!

文章分类

全部博文(191)

文章存档

2016年(2)

2015年(74)

2014年(111)

2013年(4)

我的朋友

分类: LINUX

2015-05-29 23:31:56

参考文章:
Linux 动态库剖析
为 Linux 应用程序编写 DLL
 
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
#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
阅读(847) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~