Unix/windows操作系统上java调用c/c++研究

17 篇文章 0 订阅
14 篇文章 0 订阅

原理

目前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中的函数参数,若不是基本类型,则是采用类似引用的策略,传入的函数参数对应的内容可以在函数中改变其值。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值