Unix/windows操作系统上java调用c/c++研究,unixjava
Unix/windows操作系统上java调用c/c++研究,unixjava
原理
目前java与dll交互的技术主要有3种:
- jni
Jni(Java Native Interface)是sun提供的java与系统中的原生方法交互的技术在windows\linux\unix系统中,实现java与native method互调。Jni标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI 是本地编程接口,它使得在 Java 虚拟机 (VM) 内部运行的 Java 代码能够与用其它编程语言(如 C、C++ 和汇编语言)编写的应用程序和库进行交互操作。在jdk目录的include文件夹下,包含了jni.h jni_md.h等使用JNI必须的头文件。
- jawin
sourceforge上的开源项目,同时也都是基于jni技术的windows系统上的一个应用库jawin(Java/Win32 integration project)还可以调用win32-dll动态链接库、com中的方法。
- jacob
sourceforge上的开源项目,同时也都是基于jni技术的windows系统上的一个应用库。Jacob(Java-Com Bridge)提供了java程序调用microsoft的com对象中的方法的能力。
就功能而言:jni >> jawin>jacob,其大致的结构如下图:
就易用性而言,正好相反:jacob>jawin>>jni
Jvm封装了各种操作系统实际的差异性的同时,提供了jni技术,使得开发者可以通过java程序(代码)调用到操作系统相关的技术实现的库函数,从而与其他技术和系统交互,使用其他技术实现的系统的功能;同时其他技术和系统也可以通过jni提供的相应原生接口开调用java应用系统内部实现的功能。
在windows系统上,一般可执行的应用程序都是基于native的PE结构,windows上的jvm也是基于native结构实现的。Java应用体系都是构建于jvm之上,其体系结构如图:
JNI对于应用本身来说,可以看做一个代理模式。对于开发者来说,需要使用c/c++来实现一个代理程序(jni程序)来实际操作目标原生函数,java程序中则是jvm通过加载并调用此jni程序来间接地调用目标原生函数。JNI调用过程示意图:
Windows平台
步骤:
1.编写java中的调用类
2.用javah生成c/c++原生函数的头文件
3.c/c++中调用需要的其他函数功能,实现原生函数(原则上可以调用任何资源)
4.将项目依赖的所有原生库和资源加入到java项目的java.library.path
5.生成java程序
6.发布java应用和dll库
- C++语言
环境:微软 vs2008 IDE、IBM Eclipse IED
编写java程序:
package com.java2cpp;
/**
* @author
*
*/
public class testDll {
static
{
System.loadLibrary("testCpp");
}
public native static int get();
public native static void set(int i);
public native static void callWin32API(String msg);
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
testDll test = new testDll();
test.set(10);
System.out.println(test.get());
test.callWin32API("hello world");
}
}
再在java工程目录下使用命令
javac com.java2cpp.testDll.java
javah com.java2cpp.testDll
则在该目录下生成一个com_java2cpp_testDll.h文件
该文件定义了c++中要调用的函数
再打开VS2008 新建立一个Win32 console application工程如:testCpp,再把Application type 修改为DLL类型
然后把jdk安装目录的jni.h、jni_md.h、com_java2cpp_testDll.h文件复制到testCpp工程中
在testCpp.cpp实现com_java2cpp_testDll.h定义的调用函数:
/*
* Class: com_java2cpp_testDll
* Method: set
* Signature: (I)V
* 封装c++调用,以便提供给java调用
*/
#include "stdafx.h"
#include "com_java2cpp_testDll.h"
int i = 0;
/*
*返回变量i的值
*/
JNIEXPORT jint JNICALL Java_com_java2cpp_testDll_get
(JNIEnv * evn, jclass object){
return i;
};
/*
* set方法,设置j的平方数
*/
JNIEXPORT void JNICALL Java_com_java2cpp_testDll_set
(JNIEnv * evn, jclass object, jint j){
i = j*j;
};
/*
*调用win32 API 弹出窗口
*
*/
JNIEXPORT void JNICALL Java_com_java2cpp_testDll_callWin32API
(JNIEnv * evn, jclass object,jstring jMsg){
const char *strMsgPtr = evn->GetStringUTFChars( jMsg , 0);
MessageBox( 0, strMsgPtr,"Java 调用 Win32 API 示例", 0 );
evn->ReleaseStringUTFChars( jMsg, strMsgPtr);
}
在vs2008 使用release编译 把编译后的testCpp.dll文件copy到java工程下面
在Eclipse IDE环境中或者命令行中javah com.java2cpp.testDll
运行该java程序,即可成功调用c++接口。
- C语言
Linux/UNIX平台
使用Eclipse的CDT+MinGW+GDB 开发调试环境
-
- C++ 语言
- 一:编译环境:xlC
- 二:编译环境:g++
-
- C语言
- 一:编译环境:xlc
- 二:编译环境:gcc
注意点:
1.C++中结构体,结构体数组的类型转换。有个命令javap -s xxx可以看到xxx类中包含成员对应的符号
2.java中的函数参数,若不是基本类型,则是采用类似引用的策略,传入的函数参数对应的内容可以在函数中改变其值。
相关文章
- 暂无相关文章
用户点评