在当今的软件开发领域,跨平台兼容性和集成性是至关重要的。随着技术的不断进步,各种编程语言和平台之间的界限变得模糊,开发者需要找到方法来整合这些不同的技术。在本文中,将探讨如何通过Object-Oriented JNI (OOJNI) for .NET技术实现Java与.NET平台的集成。
Object-Oriented JNI (OOJNI) for .NET是一种将标准的JavaNative Interface (JNI) SDK以类的形式暴露给.NET程序员的技术。通过这种方式,可以将JNI的引用类型,如jobject、jstring、jclass等,用.NET类进行封装。例如,JObject类封装了jobject引用,JString类保持了jstring引用,并实现了Java与.NET之间的默认字符串转换。此外,还包括了Java数组类,用于处理所有基本Java类型和对象。
OOJNIfor .NET通过一个名为ObjectOrientedJNI.JNINativeMethod的托管类来表示大多数标准的JNI函数,这些函数以静态方法的形式存在。这个SDK与JDK 1.3.x的JNI兼容,并且包含了许多有用的辅助工具,以便在.NET中轻松编写JNI代码。所有SDK都被打包成一个模块:OOJNIDOTNET.DLL,它需要在Java进程中首先加载,使用System.load(...)或System.loadLibrary(...)方法。
在下面的示例中,将展示如何在Java GUI中直接嵌入.NET控件。首先,需要编写Java代码来使用OOJNI。MainFrame类创建了一个Swing Frame窗口,该窗口用作.NET UserControl对象和关闭应用程序的JButton的容器。为了在Java中激活OOJNI,应用程序首先加载OOJNIDOTNET.DLL模块,然后加载其他JNI模块(.NET模块CSharpInJava.DLL)。
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JButton;
import javax.swing.JFrame;
public class MainFrame extends JFrame {
static {
System.loadLibrary("oojnidotnet");
System.loadLibrary("CSharpInJava");
}
FrameWindow canvas;
JButton okButton;
public MainFrame() {
super("qwerty");
initialize();
}
public void initialize() {
okButton = new JButton();
okButton.setText("Close");
getContentPane().setLayout(new BorderLayout());
getContentPane().add(canvas = new FrameWindow(), BorderLayout.CENTER);
getContentPane().add(okButton, BorderLayout.SOUTH);
canvas.setBackground(Color.blue);
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
System.exit(0);
}
});
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
System.exit(0);
}
});
pack();
setSize(200, 200);
}
public static void main(String args[]) {
new MainFrame().setVisible(true);
}
}
Java类FrameWindow用作.NET UserControl对象的容器:
import java.awt.Canvas;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
public class FrameWindow extends Canvas {
int ref = 0;
public void addNotify() {
super.addNotify();
ref = create();
}
public void removeNotify() {
dispose(ref);
super.removeNotify();
}
native int create();
native void dispose(int ref);
}
这个类保留了在addNotify调用中创建的.NET容器对象的引用,以及在removeNotify调用中实现的两个本地方法:create用于在FrameWindow中创建.NET UserControl对象,dispose用于销毁FrameWindow中的.NET对象。
Java本地方法可以在.NET代码中的任何类和命名空间中实现。唯一的限制是这些方法应该是静态的,它们的名字必须与javah.exe工具生成的一致,所有指针类型(如JNIEnv*、jobject、jstring、jweak、jclass等)应该替换为int。
using System;
using ObjectOrientedJNI;
using System.Windows.Forms;
namespace CSharpInJava {
public class NativeJavaMethods {
static int Java_FrameWindow_create(int env, int obj) {
if (!JNIEnvHelper.isInitialized())
JNIEnvHelper.init(env);
MyEmbeddedFrame embeddedWindow = new MyEmbeddedFrame(new JObject(obj));
GlobalReference gref = new GlobalReference(embeddedWindow, true);
return gref.Reference.ToInt32();
}
static void Java_FrameWindow_dispose(int env, int obj, int peer) {
((MyEmbeddedFrame)new GlobalReference(peer, false).Object).Dispose();
}
}
}
MyEmbeddedFrame类扩展了OOJNI中的EmbeddedFrame类,该类将.NET控件嵌入到Java应用程序中。在MyEmbeddedFrame中添加一个构造函数,该构造函数接收Canvas的JObject实例,并实现EmbeddedFrame的addComponents方法以初始化.NET GUI。
public MyEmbeddedFrame(JObject obj) : base(o) {
InitializeComponent();
}
在MS Visual Studio Designer中,向MyEmbeddedFrame添加Button和Editor控件(这将用所需的代码填充InitializeComponent方法)。
现在已经学会了如何在Java GUI中嵌入.NET控件,可以尝试编写代码将ActiveX嵌入到Java中,但这不是一项简单的任务。
IBM, Sun JDK1.3.x及更高版本,.NETFramework 1.1,Object-Oriented JNI for .NET(低级)可在此处获取。