java和c++混合编程尝试 我不是女神ヾ 2022-08-27 03:40 158阅读 0赞 [下载源代码][Link 1] 现在的程序员,不再像以前一样,掌握一种编程语言就可以混得有模有样了,现实的情况是,真实的项目中,通常是涉及多种编程语言,举几个简单的例子,一个软件为了快速开发,可能是使用 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++ 安装目录设置以下的环境变量 ![环境变量][41439_1259821698WtK8.jpg] 注意不要缺少 Java 的 include 和 lib 这三个红线标出部分(为源码包文件中的 cpp-env.Bat 这个批处理文件)。 设置 Java 的环境变量,如下图所示 ![java 环境变量][java] 注意红线标注的这处部分,这部分与 C++ 调用 Java 的方法时候影响非常重要(为源码包文件中的 java-env.Bat 这个批处理文件)。 在 command 模式运行这两个批处理文件后,就可以在 command 模式运行 demo 程序了。 **Java 调用 C++ 的方法** 源码文件中 %SRC%/Java-cpp 目录中的 WinFile.java 的这个文件(Java 语法规定类名与文件名必须一致),定义了一个 WinFile 类,这个类的内容如下 ![WinFile.java][] 在代码的第 18 行,声明一个带 native 属性的方法 GetFilesFromDir,这个方法传入一个字符类参数,并返回一个字符类参数,而 System.loadLibrary 则会加载指定的共享链接库,参数所示加载的动态库为 libwinfile.dll,在 windows 平台上,执行时会自动加入后缀 .dll。 在 command 模式运行以下命令: ![command模式运行以下命令][command] 第一条命令则会生成 WinFile.class 的编译文件,而第二条命令则会生成 WinFile.h 这个头文件,这个头文件包含了 WinFile.java 中的 native 的方法的 C/C++ 语言的定义。 ![头文件截图][41439_1259821694tOcG.jpg] 在 C/C++ 的语言定中,Java 语言的 String 的定义为 jstring,注意,Java 的语言的字符与程序的编码都是以 UTF-8 编码实现的,所以 Java 中的中文字符在 C++ 的方法中如果没有编码转换,则会显示为乱码。同理,在 C++ 的方法中将中文字符返回给 Java,如果没有将字符编码转为 UTF-8,在 Java 的方法显示同样会是乱码。 ![转码截图][41439_1259821694yb3G.jpg] 以上为 %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 的类。 则输出如下 ![输出截图][41439_1259821698vS95.jpg] **C++ 调用 Java 类方法** 这里演示 String 作为参数的调用返回的方法,其它的类型的方法调用也类似。 创建一个静态声明的 Java 方法 ![静态方法截图][41439_1259821689d49B.jpg] 这个方法将会接受一个 C++ 的传入的字符参数,并返回 Java 的字符类,让 C++ 函数输出内容。代码位于 %SRC%/cpp-java/WinFile.java 编译该文件后生成是一个 java 字节码的文件,它必须要运在 JVM 上,C++ 要执这些 Java 字节码,必须要运行 JVM,运行 JVM 的代码位于文件 %SRC%/cpp-java/WinFile.cpp 中,如下图所示 ![c++运行jvm截图][c_jvm] 通过 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 这个动态库加入的搜索路径中,如上面的批处理文件所示。 ![批处理截图][41439_12598216913osc.jpg] 成功建立 Java 虚拟机后,就需要动态获得类名,并通过类名和函数签名获得 Java 的方法,获得函数签名的方法是运行如下命令。 Java -s -p WinFile 则输出了我们在 Java 文件中定义的函数的签名, ![签名截图][41439_1259821692FDnA.jpg] 剩下的事情就是要负责将字符的参数进行编码调用,如下图标注出值得注意的地方 ![值得注意的地方][41439_1259821693R9UP.jpg] 参数的转换过程是为 char\* 转为 UTF8 编码再转变成为 jstring 伟入 java 方法,java 方法的返回值也应该是先转成 jstring 类型,再转为 char\* 类型再转为 GB2312。运行程序,输出结果如下 ![输出结果截图][41439_1259821693B22r.jpg] **总结** 混合语言编程要注意的是编码传输,语言运行环境的因素。例如要在 C++ 中构造 Java 的运行环境。混合语言编程有困难,但也很有趣,两种语言的优点都可以得到,不是很好的事情吗? 原文链接:http://www.vckbase.com/document/viewdoc/?id=1889 [Link 1]: http://download.csdn.net/source/1869637 [41439_1259821698WtK8.jpg]: /images/20220824/39960ee01e2f4c3b92e4a89fa472497b.png [java]: /images/20220824/6c139a912d804aa5a961398c42ef5241.png [WinFile.java]: /images/20220824/bd6a137a84a34f54af5ae9a2632f0ad0.png [command]: /images/20220824/b0332d7e8dd942a68926ba669f623b28.png [41439_1259821694tOcG.jpg]: /images/20220824/3d834c892eda44c1be8b5951fa781a8d.png [41439_1259821694yb3G.jpg]: /images/20220824/57a92ea782d340c19dade923a9437253.png [41439_1259821698vS95.jpg]: /images/20220824/be66ab8f2a334b3696ef03eba84a2d43.png [41439_1259821689d49B.jpg]: /images/20220824/eaa41ed4de534511972217418f878a28.png [c_jvm]: /images/20220824/144a81b29adc4ca58eeb5d1022d831c6.png [41439_12598216913osc.jpg]: /images/20220824/e78be8cc30044147a00e87b628ab4136.png [41439_1259821692FDnA.jpg]: /images/20220824/5d141cda26ec4457ba0e4ffd7b099cb8.png [41439_1259821693R9UP.jpg]: /images/20220824/e2050d1fe6734cce8f8940bb51da7649.png [41439_1259821693B22r.jpg]: /images/20220824/2d6fbf003b00431299f8602e99bab1ee.png
相关 Java与C++混合编程案例解析 Java和C++混合编程在实际项目中常常会出现,比如需要使用Java的面向对象特性,同时又有一些性能要求较高的部分需要用到C++。以下是一个简单的混合编程案例分析: 1. * 缺乏、安全感/ 2024年09月11日 13:30/ 0 赞/ 16 阅读
相关 python调用c++混合编程_很好的c++和Python混合编程文章(5) python与c++交互学习入门之5 这次讲讲,如何扩展c++库。通过boost.python把c++库编译成python能够调用的dll。 通过上一次的教程后,大家都应该 系统管理员/ 2023年01月09日 01:14/ 0 赞/ 109 阅读
相关 C/C++还能混合编程 什么是C/C++混合编程? 我们都知道C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出( 古城微笑少年丶/ 2022年12月31日 11:25/ 0 赞/ 87 阅读
相关 Object C与 C/C++混合编程 本文介绍下object c和C/C++混合编程。 首先介绍文件类型和可识别的代码类型。 .m文件 : 可识别object c , c代码 .mm文件: 可识别object 分手后的思念是犯贱/ 2022年09月30日 14:49/ 0 赞/ 153 阅读
相关 java和c++混合编程尝试 [下载源代码][Link 1] 现在的程序员,不再像以前一样,掌握一种编程语言就可以混得有模有样了,现实的情况是,真实的项目中,通常是涉及多种编程语言,举几个简单的例子 我不是女神ヾ/ 2022年08月27日 03:40/ 0 赞/ 159 阅读
相关 C/C++混合编程 前段时间,碰到了C,C++混合编程的需求,经过努力,顺利解决问题.现把这方面的知识做一下简单的总结: 1.当C++文件要用到C语言中的函数代码时,采用下属方法即可: 在C+ 女爷i/ 2022年06月09日 02:14/ 0 赞/ 170 阅读
相关 亲身体验CORBA: 使用java和C++混合编程 [亲身体验CORBA: 使用java和C++混合编程][CORBA_ _java_C] Posted on 2008-11-21 18:44 [ Ady Lee][Ady 左手的ㄟ右手/ 2022年05月12日 15:54/ 0 赞/ 353 阅读
相关 C++与Java混合编程 C++与Java混合编程 文章概要: 现在的程序员,不再像以前一样,掌握一种编程语言就可以混得有模有样了,现实的情况是,真实的项目中,通常是涉及多种 偏执的太偏执、/ 2022年05月12日 15:50/ 0 赞/ 167 阅读
相关 实现C#和Python高效率混合编程 为什么C\和Python要屡屡进行混合编程呢?之前我们提到了使用托管C++封装Python的核心库为一个托管dll,然后供C\调用的途径,这种方式算是一种比较科学的方式。但是它 ╰+攻爆jí腚メ/ 2022年05月06日 06:46/ 0 赞/ 795 阅读
还没有评论,来说两句吧...