岁月联盟 · 中国技术网 本站主页 | 安全认证 | 用户服务 | 技术论坛
新闻快报 | 新手学堂 | 黑客特区 | 程序语言 | 数 据 库 | 防 火 墙 | 路由交换 | 系统集成 | 服 务 器 | 存储备份 | 考试认证
Windows | Linux | Java | 协议分析 | 问题解答 | 进程大全 | 网页设计 | 多 媒 体 | 图库资料 | 软件下载 | 站内下载
  您现在的位置: 岁月联盟 >> Java >> 其他技术 >> Java正文
Java和.NET互操作究竟有什么用?
作者:未知 文章来源:本站整理 点击数: 更新时间:2007-7-23 9:51:58
, NULL, &retval);
if (FAILED(hr))
return -1;

hr = pCLR->Stop();
if (FAILED(hr))
return -1;

return (int)retval;
}

 如同Java本地接口JNI的示例一样,上面的示例假定应用程序HelloWorld.exe在执行时与.NET编译(这儿,因为我们期望正用到的(ExecuteInDefaultAppDomain)这个特殊的宿主API能有一个调用它里面Hello的类,这个类要有一个名为Main的方法,以将一个字符串当作声明处理并返回整数值。注意这和传统的C#或者VB.NET的入口通道有所不同。)都位于当前目录之下。由于.NET通用语言运行时CLR与操作系统具备更紧密的集成关系,所以CLR的动态链接库路径不需要手动设置在环境变量的PATH路径之中(关于CLR启动程序如何进行工作处理,详细内容请参考《CLI的共享源代码实现》一书)。

 当程序开发者使用非托管的C++代码编写应用成为可能,即可以加载CLR和JVM这两种不同的运行时环境来完成处理过程,这使得大部分业务逻辑的程序编写陷入开发者不敢去涉及的境地。然而吸引人的是,这可以作为锻炼编程技巧与能力的一种方式,对于我们大多数人,在这个过程中都会找到一系列的替代方案。

 首先,比如说,CLR和JVM两种技术都支持非托管代码的“Calling Down”操作(在Java虚拟机中,被称作Java本地接口,而在.NET的CLR中,被称作P/Invoke调用),这样的机制使得开发者可以在其中一个运行环境下定义功能方法,通过少量的“Trampoline(弹簧床)”编码,将程序迁移到另一个运行时环境下编译执行。例如,在Java程序中,通过本地方法接口JNI实现函数的调用操作较为繁琐,并且需要记录配置文档(比如,可以参见Liang或者Gordon的书,或者JDK中JNI的文档。)。而在实现C++本地代码调用的过程中,较为繁琐的操作是使用微软Visual Studio 2005中提供的C++/CLI或Visual Studio 2003提供的C++托管代码,来进行代码编译的过程。

 在这个步骤中,复杂之处在于程序运行时,需要确保Java虚拟机得到访问动态链接库的路径。这项工作可以分为两部分来完成:首先,当Java类函数的本地方法被程序加载时,需要询问Java虚拟机是否通过Runtime.loadLibrary()操作来请求加载共享库函数。值得注意的是,本地类库请求是在没有指定文件拓展名的情况下完成这样的操作。不指定拓展名,是因为不同的操作系统往往使用不同的约定来共享类库,所以只需指定共享类库名称即可。比如在Windows操作系统下,共享类库具有.DLL后缀,然而在Unix或Linux操作系统之下,共享类库常用的约定是使用类似于libNAME.so这样的名称。就这方面来讲,Java虚拟机首先需要在特定的操作系统中查询共享类库的约定惯例。在Windows操作系统之下,针对于加载类库的LoadLibrary()函数,官方文档中有明确的API接口说明,但所需的类库通常都包含在操作系统的安装目录中(在Windows操作系统中即为C:\WINDOWS 和 C:\WINDOWS\SYSTEM32目录),或是当前的工作目录,或者已经包含在环境变量PATH的设定之中。对于Java虚拟机的类库调用,也需要在其他两个目录中查找,即在由java.library.path系统参数指定的目录中,或是JRE运行环境所在目录的lib\i386路径之下。通常来说,推荐使用的方法是在自定义属性java.library.path中指定本地代码执行参数(在Java虚拟机启动的时候,可以设置好系统参数的路径),或者指定在JRE运行环境的i386目录中。在这个特定的例子中,很容易想象的到,指定Java虚拟机的系统参数常常是出乎开发者预期的事情(因为有时可能会有数目众多的应用服务需要设置),所以有时动态链接函数库需要被Servlet容器或应用服务器复制到Java运行环境下的函数库Lib之中。当DLL动态链接库被应用程序发现时,事实上这种所谓“混合模式”的.NET动态链接方式(即同时管理托管和非托管的代码),将会强制CLR通用语言运行时在进程启动时自动绑定,并且使得.NET通用语言运行时提供的全部功能,都集中体现在Java本地接口的动态链接库提供的操作之中。

 值得一提的是,.NET应用可以通过Trampoline(弹簧床)机制,调用Java程序代码,并使用非托管的动态链接库。然而,Java虚拟机不包含.NET所具有的那些Bootstrapping引导等神奇的机制(即“一次编写,到处运行”的特性),在进程调用中,非托管的动态链接库需要正确的加载Java虚拟机,通过与先前一样的方式来使用相同的API程序调用接口。一旦Bootstrapping引导机制就位,使用Java本地接口的反射机制,就像API调用允许类库加载,对象创建和方法调用的过程一样。通过.NET CLR程序代码来访问非托管的动态链接库,实现起来仅是如何去调用P/Invoke接口的过程,并且接口调用过程具备详尽的文档说明。

 

上一页  [1] [2] [3] [4] [5] 下一页  

 如果所有这些工作,看起来需要占用很多的时间来完成,那一定会有人帮你想到更简洁的解决方法。幸运的是,已有相关的工具和技术让这个过程变得非常简单。

 首先来看一款开源的工具包JACE(http://jace.sourceforge.net),JACE可以简化JNI本地调用的互操作过程,其设计目的是使得编写符合JNI规范的代码变得轻松简单,特别是对于Java虚拟机的Bootstrapping引导机制方面。JACE的功能相对完善,并且JACE为非托管的C++代码提供支持,这样可能意味着我们仍然需要反过头来以Windows动态链接库的方式编写各种“不安全”的代码。

 另外还有一个叫做IKVM的开源类库,现在已经成为Mono项目的一个部分。IKVM在JVM(现在(和可预见的未来)IKVM只会从CLR到JVM,不会反过来。)和CLR之间搭建了桥梁,为Java与.NET互操作提供了与其他已提到解决方案不同的实现途径。IKVM的实现并非是将Java字节码翻译成CIL代码,所以不需要将JVM加载到同一个进程之中。这包含一些有趣的含义,既然Java虚拟机没有被加载,在代码中就不需要考虑Java虚拟机所需的运行机制:即不需要Hotspot技术,不具备JMX监测程序(这意味着没有Java控制台来监测你的Java代码运行)等等。当然,既然所有的代码将转化为CIL语言,就可以利用.NET CLR通用语言运行时的所有益处,这些功能包括:CLR通用语言运行时的JIT即时编译技术,CLR性能监视器统计等功能。自从IKVM可以执行字节码翻译之后,这样的效果就对于CLR的开发者来说就变得相对透明。

 然而,我们也可能真的需要加载Java虚拟机环境,并且代码的过程代理需要在程序中释放,就像Codemesh的JuggerNET工具(JuggerNET是Java-C++代理工具的.NET版本。)生成的代码那样。它提供了两个功能:可以与.NET完善集成的Java本地接口调用API,使其可以更方便的使用.NET环境创建Java应用程序,并且提供.NET代码生成器产生.NET的代理程序,用来配置必须的参数并且执行Java对象中定义的函数方法。

上一页  [1] [2] [3] [4] [5] 下一页


  • 上一个Java:
  • 下一个Java:
  •  
    热门文章
    推荐文章
    关于我们 | 发展历程 | 网站地图 | 广告服务 | 招贤纳士 | 战略合作 | 友情链接 | 著作声明 | 联系我们
    Copyright © 2002-2007 SYUE All rights reserved.
    E_mail:Admin@Syue.Com 皖ICP备05004589号
    未经授权禁止转载、摘编、复制或建立镜像.如有违反,追究法律责任.
    传世私服 传奇世界私服 天龙八部私服 bet365 传世私服 天龙八部私服 热血江湖私服 英雄合击传奇私服 热血江湖私服 bet365 bet365