java调用c函数的实例
从C/C++到Java,再从Java回到C/C++,今天终于有机会了解了连接Java、C/C++的桥梁——JNI。哈哈!分享一下!
一、简介
JNI是Java native interface的简写,可以译作Java原生接口。Java可以通过JNI调用C/C++的库,这对于那些对性能要求比较高的Java程序或者Java无法处理的任务无疑是一个很好的方式。
二、目的:Java代码中调用C/C++代码
三、实现:假设我们的Java程序为, C程序为J2C.c, Java与C之间的通信函数名为write2proc;
那么write2proc的声明位于,实现位于J2C.c;
四、操作
1. 编写并编译Java程序
javac => s
2. 生成C/C++头文件
javah J2C => J2C.h (安装JDK后,$JAVA_HOME应该已加入$PATH, 否则使用绝对路径,例如/usr/bin/javah)
3. 编写对应的C/C++程序:J2C.c
4. 生成C/C++目标文件
gcc -I/usr/lib/jvm/java-6-openjdk-amd64/include -I/usr/lib/jvm/java-6-openjdk-amd64/include/linux -fPIC -c J2C.c => J2C.o
5. 生成C/C++共享库
gcc -shared -Wl,-soname,.1 -o .1.0 J2C.o => .1.0
6. 重命名cp .1.0 =>
7. 将共享库加入动态链接库的路径(此例为当前目录)
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
8. 执行Java程序,实现跨语言通信
java J2C
五、具体过程
1. 编写并编译
复制代码 代码如下:
import gementFactory;
import imeMXBean;
public class J2C
{
static
{
try{
// 此处即为本地方法所在链接库名
Library("j2c");
} catch(UnsatisfiedLinkError e)
{
tln( "Cannot load J2C library:n " +
ring() );
}
}
//声明的本地方法
public static native int write2proc(int pid);
public static void main(String[] args){
//获取本进程(即主线程)的pid
final RuntimeMXBean runtime = untimeMXBean();
final String info = ame();
final int index = xOf("@");
if (index != -1) {
final int pid = eInt(tring(0, index));
tln(info);
tln(pid);
write2proc(pid);
}
try{
p(8000);
} catch(InterruptedException e){
tStackTrace();
}
}
}
note:Java程序中Library参数名表示要载入的C/C++共享库,第6步生成的共享库名必须与该参数一致,即Library(Name) 对应共享库名 (共享库名必须以lib开头)
2. 生成C头文件J2C.h:javah J2C
复制代码 代码如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class J2C */
#ifndef _Included_J2C
#define _Included_J2C
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: J2C
* Method: write2proc
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_J2C_write2proc
(JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif
note:1. 头文件自动生成,不要修改它;
2. 函数JNIEXPORT jint JNICALL Java_J2C_write2proc(JNIEnv *, jclass, jint);
按照注释的说明是在文件的.类J2C的方法write2proc处定义,故C程序的实现函数必须与该处签名一致;
3. 编写C程序J2C.c
复制代码 代码如下:
#include
#include "J2C.h"
JNIEXPORT int JNICALL Java_J2C_write2proc(JNIEnv * env, jobject arg, jint pid)
{
printf("current pid is %dn", pid);
return 0;
}
4. 编译C程序
因为C程序里#include "J2C.h"而J2C.h又#include, 而gcc里面默认环境并不知道jni.h是什么东西,故编译时需要告诉编译器jni.h的位置( jni.h在jdk 的$JAVA_HOME/include下面),所以才有了上面的编译参数;
因为使用gcc编译得到动态库,在jni调用的时候,某些情况会有异常, 可尝试改用g++。
总结
1. Java中方法的原型声明与C/C++对应的实现文件定义必须一致(可以通过自动生成的C/C++头文件来比较),尤其是类名和方法名;
2. Java中Library()载入的共享库名必须与后面C/C++生成的共享库名一致。
-
java的应用范围
Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言。自从sun公司推出java语言以来,java极大受到开发者和企业的欢迎,在互联网如此发达的今天,java语言得到了广泛的应用,比如网站,游戏,电子商务等,java语言在这些领域开发占很大的比例。在全球云计算和移动互...
-
Java语法基础for语句练习
本文是本站小编搜索整理的关于Java语法基础for语句练习,供参考学习,希望对大家有所帮助!想了解更多相关信息请持续关注我们应届毕业生考试网!控制语句——for练习语句的嵌套应用累加求和,计数器循环嵌套一、语句的嵌套应用语句嵌套形式。其实就是语句中...
-
java环境变量设置path
导语:java的环境变量是怎么设置的呢?以下小编为大家介绍java环境变量设置path文章,仅供参考!java环境变量设置path环境变量是一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息。例如path,当要求系统运行一个程序而没有告诉它程序所在的完整路...
-
java设计模式:工厂模式
导语:Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。下面我们来看看工厂模式,希望对大家有所帮助。工厂设计模式★场景和问题面向接口编程是java编程中的大家所...