C++ Builder XE7 调用JAVA的JAR文件

        C++ Builder从XE6开始支持Android开发,但是在目前看来,C++ Builder for Android的技术资料非常少,我们只能从一些博客和论坛的只言片语中获取相关的信息和资源。

 

       我们知道,Android的应用程序大部分是用JAVA开发的,许多硬件制造商和服务商提供的SDK开发包,也是以JAVA的JAR库文件形式提供的,如果C++ Builder能够调用JAVA的JAR文件,那么将会大幅拓宽C++ Builder在移动开发上的应用环境,缓解在商业应用上的窘境。

 

       一直以来,C++ Builder作为Delphi的附属产品,其所获得的技术支持和关注都要比Delphi少,即使在EMB公司(Embarcadero)旗下发展到了XE7版本,这种状况仍然没有改变。许多Delphi和C++ Builder都面临的新问题,我们在网上只找到Delphi的解决方案。

 

       因此,当我在互联网上搜索“XE7调用JAR文件”时,只找到一篇文章:

              《Delphi XE7的安卓程序如何调用JAVA的JAR,使用JAVA的类》

              链接地址:http://blog.csdn.net/sunylat/article/details/41414785

 

       以及一篇EMB的帮助文档:
      
             《Using a Custom Set of Java Libraries In Your RAD Studio Android Apps》

             http://docwiki.embarcadero.com/RADStudio/XE7/en/Using_a_Custom_Set_of_Java_Libraries_In_Your_RAD_Studio_Android_Apps


        当然,Delphi和C++ Builder在一定程度上是相通的,于是尝试动手在C++ Builder下调用JAR文件。经过两天测试,终于找到了在C++ Builder XE7下调用JAR文件的方法。(注:以下方法在XE7下测试成功,如果您用的是其它版本,请自行测试)

 

        具体步骤如下:

一、生成原生桥接文件(NativeBridge File)


        所谓“原生桥接文件”,即JAR文件的定义文件,说明了存在JAR库文件里的类、类型、函数等,相当于Windows系统下的dll文件和hpp文件,原生桥接文件只是进行说明定义,具体的实现功能代码仍然在JAR文件里。

 

        如何生成原生桥接文件?EMB给出的方法是用Java2OP.exe工具,这是一个命令行程序,使用方法详见:

        http://docwiki.embarcadero.com/RADStudio/XE7/en/Java2OP.exe,_the_Native_Bridge_File_Generator_for_Android

 

        除了EMB的方案,我们还有另外两个选择:

                1. 使用Java2Pas.exe工具

               这也是一个命令行程序,通过一个批处理命令调用,作者未知。

       2. 使用JarOrClass2Pas_FlyingWang工具

              这是一个窗口程序,界面友好,是一个QQ群的牛人“老猫”开发。

 

       因为JarOrClass2Pas_FlyingWang操作简单,推荐优先使用。下面是用JarOrClass2Pas_FlyingWang根据JAR文件生成Delphi的原生桥接文件情况:


        在指定的文件夹下,会生成一个新的pas文件,这就是Delphi的原生桥接文件。

 

二、把Delphi的原生桥接文件转化为C++Builder的原生桥接文件


       上面生成的是Delphi的原生桥接文件(pas格式),要想在C++ Builder中使用,还必须将它转化为C++ Builder的原生桥接文件(hpp格式)。

 

       如何把pas文件转化为C++ Builder的原生桥接文件?EMB给出的方案是手工把pas文件转化为hpp文件!有没有搞错!!!如果是简单的JAR文件还好,其原生桥接文件就几十行代码,仔细研究还是有可能改写为hpp文件的。但是稍微复杂些的JAR文件,其其原生桥接文件达到几百上千行,各种奇怪的类型变量层出不穷,不是同时精通Delphi和C++ Builder的开发者,根本无法做到。

 

       在这里,我使用一个简单的方法,让C++ Builder自动把pas文件转化为hpp文件。

 

       打开C++ Builder XE7,新建一个Multi-Device Application项目,Target Platforms设置为Android程序,在Libraries项之下添加你的JAR文件,然后,把上面生成的Delphi桥接文件添加到工程中。你没有看错,C++ Builder XE7可以直接把Delphi的pas文件添加到工程中!

        最后,编译程序。如果该桥接文件没有错误,编译结束后,你会在工程项目文件夹中看到多出一个hpp文件,这就是C++Builder的原生桥接文件!(就这么简单,难道EMB的技术人员没有把C++Builder的这个功能告诉写帮助文档的临时工?)

 

       如果编译产生错误,你可以对Delphi的桥接文件进行修改,或者尝试改用其它两个工具来生成新的Delphi桥接文件。

 

 

三、设置工程的部署选项


       打开你的Android工程,点菜单项Project——Deployment,打开部署子窗口,点Revert to Default按钮,如图所示:


        出现Revert to default对话框:


        选中第一项“Revert for all configurationsthe active platform”,点OK。

 

       注意:不论其默认选项如何,在这里都必须选择其中一个并点OK,否则你的Android程序在调用JAR文件时将会出现“Java Class xxx could not befound”的错误。

 

       在《Delphi XE7的安卓程序如何调用JAVA的JAR》一文中,作者要求选第二项,经本人在C++ Builder XE7中测试,选第二项在调用JAR文件时可能会出现“JavaClass xxx could not be found”的错误。所以这里建议选第一项,如果程序调用JAR文件出错,再改为第二项。

 

 

四、编写调用JAR文件的代码

 

       首先了解一下示例的test.jar文件的JAVA代码,使用Eclipse编译,它简单定义了一个名字变量和一个年龄变量,并定义了四个函数,用于设置和获取名字和年龄。

public class Test {
	// 名字属性
	private String name;

	// 年龄属性
	private Integer age;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public static void main(String[] args) {
		// 实例化类
		Test test = new Test();

		// 设置默认名字
		test.setName("Delphi");
		// 设置默认年龄
		test.setAge(100);
	}
}

        按上面所述,根据JAR文件用工具生成Delphi的原生桥接文件。

       创建一个Android工程,添加JAR文件和Delphi的桥接文件,编译第一次得到C++ Builder的桥接文件。

       修改工程的部署选项,选第一项“Revert for allconfigurations the active platform”,点OK。

       在Form1内放置两个Edit组件用于设置数据,放置一个Memo组件用于显示数据。再放置三个Button,分别是“设置”、“获取”和“清空”按钮。

       在Unit1.hpp中,把C++ Builder的桥接文件include进来:

              #include"Androidapi.JNI.Test.hpp"


       注意:工程中原Delphi的桥接文件仍然保留,不要移除。

 

       在private段,定义一个JAR文件的类指针变量:

       private:

              _di_JTest testClass;

 

       在Unit1.cpp中编写调用代码:

#include <Androidapi.Helpers.hpp>   //StringToJString函数
#include <Androidapi.JNI.JavaTypes.hpp>
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
	//创建实例(这是C++ Builder创建Java类的方法)
	testClass = TJTest::JavaClass->init();

	//初始化
	testClass->setName(StringToJString(L"张三"));
	testClass->setAge(TJInteger::JavaClass->init(StringToJString(L"20")));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
	//释放实例
	testClass = NULL;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	UnicodeString strName = Edit1->Text.Trim();
	UnicodeString strAge = Edit2->Text.Trim();

	if(strName == "")
	{
		ShowMessage(L"姓名不能为空!");
		return;
	}
	if(strAge == "")
	{
		ShowMessage(L"年龄不能为空!");
		return;
	}

	testClass->setName(StringToJString(strName));
	testClass->setAge(TJInteger::JavaClass->init(StringToJString(strAge)));
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
	Memo1->Lines->Clear();

	UnicodeString strName = JStringToString(testClass->getName());
	UnicodeString strAge = JStringToString(testClass->getAge()->toString());

	Memo1->Lines->Add(strName);
	Memo1->Lines->Add(strAge);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
	Memo1->Lines->Clear();
}
//---------------------------------------------------------------------------

        在Android 4.1.1上测试成功。程序运行效果如图所示:


        所有源码及上面三个工具可在此下载:

                http://download.csdn.net/detail/realbay/8348639



【特别感谢】

       1.  JarOrClass2Pas_FlyingWang工具的作者老猫

       2. 《Delphi XE7的安卓程序如何调用JAVA的JAR》的作者sunylat


  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值