C++与Java混合编程
现在的程序员,不再像以前一样,掌握一种编程语言就可以混得有模有样了,现实的情况是,真实的项目中,通常是涉及多种编程语言,举几个简单的例子,一个软件为了快速开发,可能是使用Delphi或VB作为界面开发首选语言,底层的指令或核心算法,会使用C/C++处理,涉及数据处理的时候,为了安全和快速开发,会使用Javascript或Python等脚本语言实现数据分析处理。因此,开发者应该学习或掌握语言混合编程。 C++和Java是主流的两种编程语言,但是现在整个网上对实现这两种语言混合编程的资料少之又少,却又说之不全,并且有时多种问题现在也含糊不清,对正在学习或使用这两种语言的朋友造成很大的困扰。本人的这篇拙作,希望对使用这两种语言混合编程学习的朋友可以抛砖引玉。
实现原理
实现Java和C++的交互,使用的技术是称为JNI( Java Native Interface ),C++编写的程序,只要实现JNI生成的接口,则可以让Java程序调用,而Java编写的程序,C++调用,则需要运行Java虚拟机,通过JNI 查询调用Java实现的方法。
环境变量设置
本文中使用的Java的版本是( build 1.6.0_03-b05 ),C++的版本为VC++ 6.0版本。并根据你本机上的Java和C++安装目录设置以下的环境变量

注意不要缺少Java的include和lib这三个红线标出部分(为源码包文件中的cpp-env.Bat这个批处理文件)。
设置Java的环境变量,如下图所示

注意红线标注的这处部分,这部分与C++调用Java的方法时候影响非常重要(为源码包文件中的java-env.Bat这个批处理文件)。 在command模式运行这两个批处理文件后,就可以在command模式运行demo程序了。
Java调用C++的方法
源码文件中 %SRC%/Java-cpp目录中的WinFile.java的这个文件(Java语法规定类名与文件名必须一致),定义了一个WinFile类,这个类的内容如下

在代码的第18行,声明一个带native属性的方法GetFilesFromDir,这个方法传入一个字符类参数,并返回一个字符类参数,而 System.loadLibrary则会加载指定的共享链接库,参数所示加载的动态库为libwinfile.dll,在windows平台上,执行时会自动加入后缀.dll。 在command模式运行以下命令:

第一条命令则会生成WinFile.class的编译文件,而第二条命令则会生成WinFile.h这个头文件,这个头文件包含了WinFile.java中的native的方法的C/C++语言的定义。

在C/C++的语言定中,Java语言的String的定义为jstring,注意,Java的语言的字符与程序的编码都是以UTF-8编码实现的,所以Java中的中文字符在C++的方法中如果没有编码转换,则会显示为乱码。同理,在C++的方法中将中文字符返回给Java,如果没有将字符编码转为 UTF-8,在Java的方法显示同样会是乱码。

以上为%SRC%/Java-cpp/WinFile.cpp的部分代码,代码中实现了两个函数,一个是将UTF-8转为GB2312,另一个为将GB2312转为UTF-8,而jni.h这个头文件中也同时提供了jstring与char*的类型之间转换函数。
1.<b>GetStringUTFChars</b> <b>NewStringUTF</b>运行如下编译命令:
1.<b>cl -GX -LD WinFile.cpp -FelibWinFile.dll</b> 则生成libWinFile.dll这个动态库(注意,生成的名称要与System.loadLibrary这个函数内的参数的名称一致),运行这个Java的类。
则输出如下

C++调用Java类方法
这里演示String作为参数的调用返回的方法,其它的类型的方法调用也类似。
创建一个静态声明的Java方法

这个方法将会接受一个C++的传入的字符参数,并返回Java的字符类,让C++函数输出内容。代码位于%SRC%/cpp-java/WinFile.java
编译该文件后生成是一个java字节码的文件,它必须要运在JVM上,C++要执这些Java字节码,必须要运行JVM,运行JVM的代码位于文件%SRC%/cpp-java/WinFile.cpp中,如下图所示

通过JNI_CreateJavaJVM这个函数,C++则会运行JVM,注意,生成的WinFile.exe这个文件提示需要jvm.dll,但是千万不要将jvm.dll从jre这个目录拷贝到WinFile.exe这个目录,因为jvm能够正常运行,必须依赖jre的java库和其它的动态库,虽然从dependency看不出jvm.dll依赖jre中的其它库和文件。如果把jvm.dll抽离出来与WinFile.exe位于同一目录,虽然能够运行,但JNI_CreateJavaJVM调用永远失败的。解决方法,就是将jvm.dll这个动态库加入的搜索路径中,如上面的批处理文件所示。

成功建立Java虚拟机后,就需要动态获得类名,并通过类名和函数签名获得Java的方法,获得函数签名的方法是运行如下命令。
1.<b>Java -s -p WinFile</b>则输出了我们在Java文件中定义的函数的签名,

剩下的事情就是要负责将字符的参数进行编码调用,如下图标注出值得注意的地方

参数的转换过程是为char*转为UTF8编码再转变成为jstring伟入java方法,java方法的返回值也应该是先转成jstring类型,再转为char*类型再转为GB2312。运行程序,输出结果如下

总结
混合语言编程要注意的是编码传输,语言运行环境的因素。例如要在C++中构造Java的运行环境。混合语言编程有困难,但也很有趣,两种语言的优点都可以得到,不是很好的事情吗?
C++与Java混合编程的更多相关文章
- java matlab混合编程之返回值Struct类型
java matlab混合编程的时候当返回值是Struct类型(matlab中的返回类型)如何来取得(java中)其值? 上网找,看到这个网页:http://www.mathworks.cn/cn/h ...
- Java语言与C语言混合编程(2)--在Java中调用C语言本地库
在上一篇文章中介绍了Java语言中的native关键字,以及Java语言调用C语言的编译生成本地动态链接库(DLL)实现加法运算的小例子,本文通过一个更加详细的例子,深入讲解Java语言调用C语言的函 ...
- Java语言与C语言混合编程(1)--Java native 关键字
一. 什么是 native Method 简单地讲,一个 native Method 就是一个java调用非java代码的接口.一个 native Method 是这样一个java的方法:该方法的实现 ...
- 如玫瑰一般的PHP与C#混合编程
故事背景是这样的,有一套项目,服务器端是用C#写的,为了完成某种事情,它需要使用到一个组件,这个组件很小但很重要,很不巧的是,这个这个组件是用PHP语言写的,如果为了使用这个组件而专门搭建一个PHP的 ...
- 20145212 实验五《Java网络编程》
20145212 实验五<Java网络编程> 一.实验内容 1.运行下载的TCP代码,结对进行,一人服务器,一人客户端: 2.利用加解密代码包,编译运行代码,一人加密,一人解密: 3.集成 ...
- 20145337实验五Java网络编程及安全
20145337实验五Java网络编程及安全 实验内容 掌握Socket程序的编写 掌握密码技术的使用 设计安全传输系统 实验步骤 基于Java Socket实现安全传输 基于TCP实现客户端和服务器 ...
- JAVA课程实验报告 实验五 Java网络编程及安全
北京电子科技学院(BESTI) 实 验 报 告 课程:Java程序设计 班级:1353 姓名:韩玉琪 学号:20135317 成绩: 指导教师:娄嘉 ...
- paip. 混合编程的实现resin4 (自带Quercus ) 配置 php 环境
paip. 混合编程的实现resin4 (自带Quercus ) 配置 php 环境 #---混合编程的类型 1.代码inline 方式 2.使用库/api 解析方式. #----配置resin 支 ...
- 用c/c++混合编程方式为ios/android实现一个自绘日期选择控件(一)
本文为原创,如有转载,请注明出处:http://www.cnblogs.com/jackybu 前言 章节: 1.需求描述以及c/c++实现日期和月历的基本操作 2.ios实现自绘日期选择控件 3.a ...
随机推荐
- 以太网基础知识0(UDP和TCP有什么区别)
参考:http://zhidao.baidu.com/link?url=GSIg9_zFhWi6PHezalQveRwwUsU0as7k6MFd05r-cruLT1yDABARraHkuq8ohdIR ...
- Oracle行转列SQL
-- Create table /*create table TEST_TABLE ( STUDENT VARCHAR2(200), SUBJECT VARCHAR2(200), GRADE NU ...
- python地址解析经纬度,城市
1.地址列表 1.txt 上海市普陀区梅川路299-301号 浙江省杭州市拱墅区丰登路305-311号1层 江苏省南京市鼓楼区碧树园86号101室 浙江省宁波市江北区范江岸路38弄6号-10号1层商铺 ...
- Alluxio 内存存储系统部署
一.文件下载和解压 1)下载地址:http://www.alluxio.org/download 2) 解压命令如下: $ wget http://alluxio.org/downloads/file ...
- HTML源文件编码的问题
刚才使用sublime text编辑html文件,在html中使用meta tag指定了charset,如下 <meta http-equiv="content-type" ...
- c++之——重载、重写、重定义
函数重载: 必须在同一个类中进行: 子类无法重载父类的函数,父类同名函数将被子类名称覆盖: 重载是在编译期间根据参数类型和个数决定函数的调用(静态联编). 函数重写与重定义: 重写: 必须发生在基类和 ...
- python学习笔记(13)--向文件夹插入课文朗读
说明: 1. 2016年初刚学python写的一段代码,找到了一个walk函数,研究了半天.文件复制粘贴,研究了半天.正则匹配,研究了半天,期间被斜杠差点搞死.后来做完了跟CZ炫耀,他说python里 ...
- C++ test的使用
http://www.parasoft.com/jsp/trial_request.jsp?itemId=303 去下载,原来是个商业的测试软件,还要去购买,这个成本太大了.. http://down ...
- 【Unity笔记】UGUI物体的Rect Transform组件(Pivot中心点,Anchor锚点)
Pivot:自身中心点,图标是小蓝点.表示图片以哪个点来计算坐标值.默认在UI元素的几何中心点(0.5, 0,5). Anchor:锚点,图标是四个小三角形.表示该UI元素以父物体的哪个位置作为缩放参 ...
- Maven学习:项目之间的关系
Maven不仅可以定义一个项目中各个模块之间的关系,还可以更延伸一步定义项目与项目之间的关系. 定义父子项目的好处还是挺多的.