65.9K
CodeProject 正在变化。 阅读更多。
Home

从 Java 程序中使用 VC++ 组件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.15/5 (10投票s)

2006年9月12日

CPOL

3分钟阅读

viewsIcon

155969

downloadIcon

1295

本文介绍如何从 Java 程序访问本地 Windows DLL,以利用 Windows 提供但 Java 无法直接使用的功能。文章介绍了 JNI(Java 本地接口)。

Sample Image - JNITest.jpg

引言

JNI 是我最喜欢的 Java 编程框架;它允许你使用本地创建的代码。例如,如果你想从你的 Java 代码中使用任何 Windows API(即 dll),你可以使用 JNI。

Java 最大的优势在于平台独立性。但是,有时此功能会使 Java 程序与本地平台的集成非常困难。

例如,在我们的项目中,我们使用 MSMQ(Microsoft Messaging Queue)作为排队机制来维护消息(以避免消息丢失),然后再将它们写入数据库。Microsoft 提供了 MSMQ API,这是一个 Windows API。但是我们的程序是用 Java 编写的,Java 无法直接访问此 VC++ API(dll)。因此,我们决定创建一个中间 DLL,它将充当 Java 和 VC++ 之间的桥梁(我们使用了 Java 本地接口或 JNI 技术)。

在继续之前,你应该了解/熟悉一些术语。

  • 本地方法:本地方法是在 .java 文件中声明,并在你的本地代码中定义的方法。(对于 Windows,它在 VC++ 中)。
  • 静态块:Java 中的静态块是在任何其他事情发生之前执行的代码部分。

让我们开始吧。首先,编写你的 Java 程序,并声明本地方法。以下代码来自示例源码。

public class JNITest 
{
     static 
       {
        System.loadLibrary("JNITest");  // Loading dll in memory 
       }
        
    native void showMessage( String str);  // Declaring native method
    public JNITest()
    {
        System.out.println( "In the constructor of the Java program" );        
    }
        
    public static void main( String s[] )
    {
         JNITest JNT = new JNITest();
         JNT.showMessage("Passing string from Java");  
    } 
}

在上面的代码中,我们声明了名为 `showMessage` 的本地方法,并在 `JNITest` 类的对象上调用它。

执行以下步骤:

  1. 编译代码以生成 .class 文件。
  2. 在 JDK 文件夹中,你会找到一个名为 **javah** 的实用程序。
  3. 进入命令提示符并执行 **javah -jni JNITest**

执行上述命令将生成文件 *JNITest.h*。此 .h 文件包含在我们的 Java 代码中声明的本地方法的 VC++ 等效名称。

创建 JNI DLL

我们已经完成了一半。

现在在 Visual Studio(或任何其他 win32 IDE)中创建一个简单的 dll 项目,并将上面的 .h 文件添加到项目中。

将 JRE\INCLUDE 文件夹的路径添加到你的 **includes** 中,以获取包含文件 *jni.h*。

现在你将以略微不同的方式找到在 .java 文件中声明的方法的名称。

在上述情况下,你将得到:

JNIEXPORT void JNICALL Java_JNITest_showMessage(JNIEnv *, jobject, jstring);

这里,**第三个参数**是来自 Java 程序的参数。你可以将其转换为本地形式,如下所示:

const char *strS1 = env->GetStringUTFChars( s1, 0);

在这里,你可以将 `strS1` 用作 C++ 字符串。在演示程序中,我使用它在消息框中显示它。`JNIEnv` 有许多方法可以将各种类型的数据从 Java 转换为 C++。

使用后必须释放字符串,这不是自动的。JNI 活动被认为是 JVM 的外部活动,因此它不会抛出任何可以在 Java 代码中捕获的异常。如果你在离开函数之前忘记释放字符串,这可能会导致你的 JVM 崩溃。

你可以使用函数 `ReleaseStringUTFChars` 释放字符串。

env->ReleaseStringUTFChars( s1, strS1);

整个代码如下所示:

JNIEXPORT void JNICALL Java_JNITest_showMessage(
    JNIEnv * env, jobject job, jstring str )
{    
       const char *strMsgPtr     = env->GetStringUTFChars( str , 0);    
       //Converting string to C++ character pointer
      
       MessageBox( 0, strMsgPtr,"Message box from VC++ ", 0 ); 
       //Using the string 

       env->ReleaseStringUTFChars( str, strMsgPtr);  
       // Releasing the string ( character pointer )
}

现在你可以自由地使用 Windows(或 VC++)组件——你现在可以访问任何 Windows API。

构建 dll 并将其放置在你的 Java 程序的文件夹中(包含你的 .class 文件的文件夹)。

现在运行你的 Java 程序。

注意:如果出现 *UnsatisfiedLinkError*,请检查你的方法签名(原型)。它必须与 .h 文件中提供的一致。

使用 JNI,你可以从 Java 程序访问 Windows 提供的各种功能。

© . All rights reserved.