java和c++混合编程尝试

下载源代码

  现在的程序员,不再像以前一样,掌握一种编程语言就可以混得有模有样了,现实的情况是,真实的项目中,通常是涉及多种编程语言,举几个简单的例子,一个软件为了快速开发,可能是使用 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* 的类型之间转换函数。

GetStringUTFChars

NewStringUTF

运行如下编译命令:

cl -GX -LD WinFile.cpp -FelibWinFile.dll

  则生成 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 的方法,获得函数签名的方法是运行如下命令。

Java -s -p WinFile

则输出了我们在 Java 文件中定义的函数的签名,

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

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

总结

  混合语言编程要注意的是编码传输,语言运行环境的因素。例如要在 C++ 中构造 Java 的运行环境。混合语言编程有困难,但也很有趣,两种语言的优点都可以得到,不是很好的事情吗?

原文链接:http://www.vckbase.com/document/viewdoc/?id=1889

java和c++混合编程尝试,布布扣,bubuko.com

时间: 05-01

java和c++混合编程尝试的相关文章

混合编程杂谈

此文抛砖引玉,仅作记录,希望广大网友多多指正,谢谢! 最近接触了混编的项目,项目是02年开发的,当时使用的是VC6.0+TCL脚本,VC负责前台的界面显示,后台全部用TCL实现,由于公司规定不能截图出来,望大家海涵,大概描述一下工具的功能,主要用于检查某种负责通信的服务是否配置.运行等正常.大体功能如下:左边是局点的控制描述,主要记录有局点名称.局点IP.连接方式.用户名密码.是否使用内置FTP等信息,右边是每一个局点要执行的任务配置项,主要分为两个大项:健康检查和信息收集. 最近有一个新的需求

C++与Java混合编程

http://www.cnblogs.com/lxshanye/p/3209542.html 现在的程序员,不再像以前一样,掌握一种编程语言就可以混得有模有样了,现实的情况是,真实的项目中,通常是涉及多种编程语言,举几个简单的例子,一个软件为了快速开发,可能是使用Delphi或VB作为界面开发首选语言,底层的指令或核心算法,会使用C/C++处理,涉及数据处理的时候,为了安全和快速开发,会使用Javascript或Python等脚本语言实现数据分析处理.因此,开发者应该学习或掌握语言混合编程. C

SWIG - 同Java的混合编程

同Java的混合编程 - SWIG 最后更新日期:2014-04-20 阅读前提:推荐已经阅读<同C#的混合编程_SWIG入门>, 有Eclipse下编写JavaProject的经验. 作者: Kagula 环境:Windows 8.1 64bit(英文版).VisualStudio 2013 Update1(英文版).SWIG Win 3.0.0 .JDK 1.6.0_45 64bit.eclipse-jee-kepler-SR1-win32-x86_64 正文: 新建C++工程用于测试Ja

用c/c++混合编程方式为ios/android实现一个自绘日期选择控件(一)

本文为原创,如有转载,请注明出处:http://www.cnblogs.com/jackybu 前言 章节: 1.需求描述以及c/c++实现日期和月历的基本操作 2.ios实现自绘日期选择控件 3.android实现自绘日期选择控件 目的: 通过一个相对复杂的自定义自绘控件来分享: 1.ios以及android自定义自绘控件的开发流程 2.objc与c/c++混合编程 3.android ndk的环境配置,android studio ndk的编译模式,swig在android ndk开发中的作

Java TCP/UDP socket 编程流程总结

最近正好学习了一点用java socket编程的东西.感觉整体的流程虽然不是很繁琐,但是也值得好好总结一下. Socket Socket可以说是一种针对网络的抽象,应用通过它可以来针对网络读写数据.就像通过一个文件的file handler就可以都写数据到存储设备上一样.根据TCP协议和UDP协议的不同,在网络编程方面就有面向两个协议的不同socket,一个是面向字节流的一个是面向报文的. 对socket的本身组成倒是比较好理解.既然是应用通过socket通信,肯定就有一个服务器端和一个客户端.

Qt Quick 之 QML 与 C++ 混合编程详解

Qt Quick 技术的引入,使得你能够快速构建 UI ,具有动画.各种绚丽效果的 UI 都不在话下.但它不是万能的,也有很多局限性,原来 Qt 的一些技术,比如低阶的网络编程如 QTcpSocket ,多线程,又如 XML 文档处理类库 QXmlStreamReader / QXmlStreamWriter 等等,在 QML 中要么不可用,要么用起来不方便,所以呢,很多时候我们是会基于这样的原则来混合使用 QML 和 C++: QML 构建界面, C++ 实现非界面的业务逻辑和复杂运算. 请给

阿里Java开发手册之编程规约

阿里Java开发手册之编程规约 对于程序员来说,编程规范可以养成良好的编程习惯,提高代码质量,降低沟通成本.就在2月9号,阿里出了一份Java开发手册(正式版),分为编程规约,异常日志,MySQL规约,工程规约,安全规约五个章节.这里我根据阿里的编程规约,重点记录(黑色加粗部分)自己还未做好的一些规范,同时方便查阅. ++阿里Java开发手册下载地址++ 编程规约 一.命名规约 [强制]代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束. 反例: _name / __name

读懂Java中的Socket编程(转)

Socket,又称为套接字,Socket是计算机网络通信的基本的技术之一.如今大多数基于网络的软件,如浏览器,即时通讯工具甚至是P2P下载都是基于Socket实现的.本文会介绍一下基于TCP/IP的Socket编程,并且如何写一个客户端/服务器程序. 餐前甜点 Unix的输入输出(IO)系统遵循Open-Read-Write-Close这样的操作范本.当一个用户进程进行IO操作之前,它需要调用Open来指定并获取待操作文件或设备读取或写入的权限.一旦IO操作对象被打开,那么这个用户进程可以对这个

【5.1送礼】国内第一部Matlab和C#.Net混合编程入门级视频教程【完全免费】

上一次写博客很久了,一直在忙彩票分析系统架构的事情,写博客真是件费神的事情,非常花时间.今天抽空发布这篇博客,是为了开源一部自己录制的视频教程-Matlab和C#.Net混合编程视频教程[入门级].下面说说这部视频教程的来由和一些事情,想获取的仔细看看,别忘了点[推荐]哦! 一.为啥要开源 1.1 视频的来源 这部视频教程是在2012年年底闲时比较多,当初也是很多朋友,网友提出这个Matlab.Net混合编程入门比较难,没有资料,所有就特意录制了一部比较简单的视频教程.并有条件的对广大网友免费开