Java通过JNI调用delphi程序.doc_第1页
Java通过JNI调用delphi程序.doc_第2页
Java通过JNI调用delphi程序.doc_第3页
Java通过JNI调用delphi程序.doc_第4页
Java通过JNI调用delphi程序.doc_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Java通过JNI调用delphi程序2008年03月25日 星期二 下午 04:25调用Delphi程序 通过在JNI框架内实战Java程序调用C程序,我们可以推导出Java程序基于JNI规范调用异质语言编写的程序的必要条件: 被调用的函数和方法被封装在标准的动态链接库中,由动态链接库将其输出。这是整个JNI规范存在的基础。 在两种语言之间存在着一个充当“翻译”角色的中介。在Java调用C语言的场合中,这个中介就是jni.h:在开发被调用的动态链接库的过程中,首先引入jni.h,然后实现利用javah生成的头文件中定义的函数即可。以上是实践JNI规范的必要条件。从中可以推导出以下的结论任何语言只要能满足这两个条件,那么这种语言就具备被Java程序调用的可能性。在Windows平台上,主流开发语言都能编译产生动态链接库;但是能找到一种类似jni.h、在两种异质语言之间映射数据结构的中介却不是非常容易。本章介绍Java语言如何在JNI框架内调用Delphi编译产生的动态链接库,在此过程中发挥类似jni.h作用的是jni.pas同样由Sun公司开发,针对Delphi的JNI框架的实现。Delphi是诞生于Win32时代的一款优秀的IDE,曾经拥有庞大的开发群体。随着Borland(相信本书的读者对Borland公司不会陌生,不仅因为它传奇般的故事,也因为它的另一款主打产品JBuilder)公司主营业务的转型,也随着Windows平台从Win32时代向.NET时代的迁移,Delphi也正在经历着深刻的蜕变。尽管如此,Delphi仍然保持着一年一个大版本的升级速度。Delphi拥有众多的成功案例,因此本书在介绍完Java和C语言的互操作之后,安排一节内容介绍Java如何调用Delphi程序。本节涉及的Delphi程序在Delphi 7.0环境下编译通过。jni.pas在配书光盘中本节的源码目录中可以找到。15.3.1 简单例程在本章的顺序编排方面,先以一个最简单的例程“开场”,在这个例程中不涉及任何的参数传递,只要Java主调程序能够触发Delphi方法的执行便达到目的。Delphi基于Object Pascal语言,Pascal语言的方法分为函数(Function)和过程(Procedure)两类。 我们先来看看做为主调方的Java程序。程序很简单:在HelloWorld寻找并载入Project1.dll,并定义本地方法:displayHelloWorld()。代码清单15-15 调用Delphi函数的例程HelloWorld1. public class HelloWorld2. 3. public native void displayHelloWorld();4. static5. 6. System.loadLibrary(Project1);7. 8. Main则负责调用HelloWorld。代码清单15-16 调用Delphi函数的例程Main1. public class Main2. 3. public static void main(String args)4. 5. HelloWorld hw = new HelloWorld();6. hw.displayHelloWorld();7. 8. 接下来的工作是编写Delphi程序。关于Delphi语法、Delphi工程的结构,以及如何在Delphi中开发动态链接库,不准备介绍,本书假设读者们已经掌握相关知识。以下是Delphi工程文件(.dpr文件)在Delphi中如果不涉及任何窗体的话,是无须创建单元文件的。代码清单15-17 调用Delphi函数的例程Project1.dpr1. library HelloWorldImpl;2.3. uses4. JNI;5.6. procedure Java_HelloWorld_displayHelloWorld(PEnv: PJNIEnv; Obj: JObject); $IFDEF WIN32 stdcall; $ENDIF $IFDEF LINUX cdecl; $ENDIF7. begin8. WriteLn(Hello world!);9. end;10.11. exports12. Java_HelloWorld_displayHelloWorld;13.14. end.可以看到,在JNI框架内的Delphi程序和C程序很类似,首先引入了jni.pas,而且无论方法的命名,还是固有的两个输入参数:PJNIEnv和Jobject。编译以上工程文件后将产生动态链接库文件Project1.dll。15.3.2 关闭窗口实用程序我们知道,在原生的Windows程序中查找一个窗口的句柄和关闭一个窗口是很容易做到的,只需调用Win32 API即可;可是Java程序却没有和操作系统直接交互的能力,要实现这个需求就比较困难了。跨越虚拟机、实现和操作系统的直接交互,正是JNI的一大存在价值。本节将演示Java程序如何“借助”Delphi程序的本领,实现自身能力的提升。相比较上一节的例程,本例程具有以下需要注意的亮点: Delphi程序提供两个方法,一个是函数,另一个是过程。 Java程序向Delphi方法传入参数。 Delphi函数向Java程序返回函数结果。 在Delphi程序中使用JNI上下文,即PJNIEnv变量。以下是声明本地方法的Java类FindWindow:代码清单15-18 调用Delphi函数的例程FindWindow1. class FindWindow2. 3. public native boolean ifExistsWindow(String itemName);4. public native void closeWindow(String itemName);5. static6. 7. System.loadLibrary(Project1);8. 9. Delphi程序将向Java程序输出两个方法:boolean ifExistsWindow(String)和void closeWindow(String),两个方法完成的功能分别是查找窗口和关闭窗口。按照JNI命名约定,在Delphi程序中,这两个方法将被命名为:Java_FindWindow_ifExistsWindow()和Java_FindWindow_closeWindow()。以下是Java主程序Main。代码清单15-19 调用Delphi函数的例程Main1. import java.io.*;2.3. class Main4. 5. public static void main(String args)6. 7. FindWindow fw = new FindWindow();8. boolean result=fw.ifExistsWindow( TITLE1 );9. if(result)10. fw.closeWindow( TITLE1 );11. 12. Main.java的执行逻辑是,根据窗口标题查找窗口,如果该窗口存在的话,则予以关闭。在Main.java的第8行调用了一个返回布尔值的Delphi方法ifExistsWindow(),可见Delphi的布尔类型返回值可以在Java程序中直接使用。在程序的第10行调用了一个Delphi过程closeWindow()。两次调用传入的字符串参数是对应着被查找和关闭的窗口标题的配置项名。本例假设需要查找和关闭记事本程序,记事本的窗口标题是“TranVerCtl.ini”,则配置文件TranVerCtl.ini的内容如下:PARAMTITLE1=无标题 - 记事本下面是Delphi工程文件Project1.dll的源代码。代码清单15-20 调用Delphi函数的例程Project1.dpr1. library FindWindowTool;2.3. uses4. JNI,Windows,SysUtils,Messages,inifiles;5.6. function Java_FindWindow_ifExistsWindow(PEnv: PJNIEnv; Obj: JObject; itemName:JString):JBoolean; $IFDEF WIN32 stdcall; $ENDIF $IFDEF LINUX cdecl; $ENDIF7. var8. JVM: TJNIEnv;9. hWndClose:HWnd;10. ini:tinifile;11. item:String;12. caption:String;13. begin14. JVM := TJNIEnv.Create(PEnv);15. item:=JVM.JStringToString(itemName);16. ini:=tinifile.create(.TranVerCtl.ini);17. caption:=ini.readstring(PARAM,item,);18. ini.Free;19. writeln(窗口名:+caption);20. hWndClose := findwindow( nil , pchar(caption) );21. if hWndClose0 then22. begin23. result:=true;24. writeln(找到该窗口!);25. end26. else27. begin28. result:=false;29. writeln(没有找到该窗口!);30. end;31. end;32.33. procedure Java_FindWindow_closeWindow(PEnv: PJNIEnv; Obj: JObject; itemName:JString); $IFDEF WIN32 stdcall; $ENDIF $IFDEF LINUX cdecl; $ENDIF34. var35. JVM: TJNIEnv;36. hWndClose:HWnd;37. ini:tinifile;38. item:String;39. caption:String;40. begin41. JVM := TJNIEnv.Create(PEnv);42. item:=JVM.JStringToString(itemName);43. ini:=tinifile.create(.TranVerCtl.ini);44. caption:=ini.readstring(PARAM,item,);45. ini.Free;46. hWndClose := findwindow( nil , pchar(caption) );47. if hWndClose0 then48. begin49. SendMessage(hWndClose,WM_CLOSE,0,0);50. writeln(关闭成功!);51. end52. else53. writeln(关闭失败!);54. end;55.56. exports57. Java_FindWindow_ifExistsWindow,Java_FindWindow_closeWindow;58.59. end.Delphi程序如何读取配置文件、如何查找和关闭窗口不是我们最关注的,请注意以下方面。 JString和JBoolean等数据类型:这些由jni.pas定义的特有的数据类型,对应着Java语言中的数据类型。表15-1是Java和Delphi的基础数据类型的对照关系,以及jin.pas对这些Java数据类型的重定义。表15-1 Java和Delphi的基础数据类型的对照关系Java TypeDelphi TypeNative TypebooleanBooleanjbooleanbyteShortintjbytecharWideCharjchardoubleDoublejdoublefloatSinglejfloatintLongintjintlongInt64jlongshortSmallintjshortvoidN/Avoid JNI上下文的获取方式:PJNIEnv和JObject两种类型的输入参数,是遵循JNI规范的方法所固有的。 jni.pas中定义的数据类型转换方法:和jni.h定义了一系列类似GetStringUTFChars()的类型转换函数一样,jni.pas为Object Pascal和Java两种语言之间数据类型的转换提供了方法,如例程中的JStringToString()。正如读者们所看到的,在JNI框架内,Java程序调用C和Delphi程序,其步骤和方式是大同小异的,区别主要在语法方面。如果有兴趣,或者在实际工作中需要大规模使用Java程序调用D

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论