一个JNI的小例子

最近要在JAVA程序里调用C++写的.dll文件,要用到JNI技术,找了些资料,自己做了个小例子.步骤如下:
JAVA 代码:
public class testdll{
 static {
  System.loadLibrary("DLL");
 }
public native static int get();
public native static void set(int i);
public static void main(String[] args) {
 testdll test = new testdll();
 test.set(100);
 
 System.out.println(test.get());
 }
}
 
编译,然后使用javah -jni testdll生成testdll.h文件
 
C代码:
#include"testdll.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

int i = 0;
JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass)
{
 return i;
}

JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint j)
{
 i = j;
}
 
如果有如下错误:
fatal error C1083: Cannot open include file: 'jni.h': No such file or directory
将以下文件:

/jdk/include/jni.h

/jdk/include/win32/jawt_md.h

/jdk/include/win32/jni_md.h

复制到Visual Studio.net的安装目录下的/Vc7/include目录中

如果是VC6.0,自己找相应的目录即可!

然后编译,成功后,将生成的.dll文件copy到JAVA文件的同一级目录中

运行java程序````````

  ==================================================
14:04 2007-8-15

Implementation JNI by prompt:
1. Code java source file, note:
   static {
        System.loadLibrary("TestDLL");
   }
  
2. javac ....java

3. javah -jni ... (generate TestDLL.h)

4. Create TestDLL.c (the implementation of native method) [note: add argument name]
    #ifdef __LCC__
    /**
     * Valentin Valchev (Bulgaria, www.prosyst.com)
     * This is the standart implementation of Java 2 OnLoad and OnUnload native
     * library calls. This template defines them empty functions
     */
    JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)  
    {
        return JNI_VERSION_1_2;
    }
    JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)
    {
    }
    #endif
  
  
5. lcc -IC:/jdk1.5/include -IC:/jdk1.5/include/win32 -c TestDLL.c

6. lcclnk -dll TestDLL.obj -o TestDLL.dll

over

===================================================
Java Native Interface on Windows
--------------------------------

General Steps:
--------------
1) Create .java source file, with the following three things:
  - a main method
  - a native method (i.e. declaration only)
  - a static block with call to System.loadLibrary("nameofdllfilewithoutextension")

2) Compile this into a .class file

3) Use javah with -jni flag to create a .h header file.

4) Create a .c source file, with the native method implementation in it. The function
   declaration must EXACTLY MATCH the declaration in the .h header file (copy/paste it!).
   Also, one must #include <jni.h> and #include "theheaderfile.h".
   (NOTE: see example below for a slight HACK)

5) Compile the .c source file into "nameofdllfilewithoutextension".dll

6) Run the Java application. It will load the .dll file at runtime.



Example, using lcc-win32 compiler:
----------------------------------
We will create a JNITest application, where a .java file calls a native method which
simply performs some variation of Hello World! In this example we assume that the
current directory contains all the project files described in what follows. We also
assume that the compiler binaries are located at C:/lcc/bin and that the JNI files
are located at C:/jdk1.3.0_02/include -- but it's easy to change these paths below.
Note: if you don't have lcc-win32, do a Google search on it, download it and install
it. It takes about 5 minutes. The installer works well. I installed it into C:/lcc



1) Create JNITest.java with elements described above.

2) javac -classpath . JNITest.java

3) javah -jni JNITest

4) We now have the following files: JNITest.java JNITest.class JNITest.h

5) Create JNITestImpl.c (with implementation of method(s) declared in JNITest.h).
   On my system (win2k), the .h file created by javah does not have the the complete
   function declaration: only argument types, but no argument names are given. This
   works okay in the .h file, but when you copy and paste it into the implemention .c
   file, you'll need to add argument names. See the source code below for details:

   We also need the following, more significant HACK. Because of some issues with lcc,
   it is necessary to include some extra C code in the implementation .c file. You
   can search Google Groups for 'dll lcc-win32 jni export'. If you look carefully
   (you need to explicitly select "Complete Thread") there's an explanation by the
   author of lcc-win32, and the following workaround: you can add this code at the
   bottom of your JNITestImpl.c file.


#ifdef __LCC__

/**
 * Valentin Valchev (Bulgaria, www.prosyst.com)
 * This is the standart implementation of Java 2 OnLoad and OnUnload native
 * library calls. This template defines them empty functions
 */
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)  
{
    return JNI_VERSION_1_2;
}
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)
{
}
#endif

6) Compile JNITestImpl.c into a .obj file. This can be tricky. Here's how in this case:

  C:/lcc/bin/lcc -IC:/jdk1.3.0_02/include -IC:/jkd1.3.0_02/include/win32 JNITestImpl.c

7) You now have the following files: JNITest.java JNITest.class JNITest.h JNITestImpl.c JNITestImpl.obj

8) Now we must use the 'Linker' to create a .dll file:

  C:/lcc/bin/lcclnk -dll JNITestImpl.obj -o jnitest.dll

  This assumes the .java file has the following line:
  
     static { System.loadLibrary("jnitest"); }

9) This not only creates the file jnitest.dll, but also a bunch of others. They don't matter much.

10) Run the program:  java -classpath . JNITest



Source Code for this Example:
------------------------------

File: JNITest.java
------------------
public class JNITest
{
    public static void main(String args[])
    {
        System.out.println("Beginning main() in JNITest.");

        JNITest test = new JNITest();
        test.displayHelloWorld();

        System.out.println("Completed main() in JNITest.");
    }

    public native void displayHelloWorld();

    static {
        System.loadLibrary("jnitest");
    }
}


File: JNITestImpl.c
-------------------
#include <jni.h>
#include "JNITest.h"
#include <stdio.h>

/*
 * This is virtually the same function definition as defined in JNITest.h
 * but we've added argument names: 'env' and 'obj'
 */
JNIEXPORT void JNICALL Java_JNITest_displayHelloWorld(JNIEnv *env, jobject obj)
{
    printf("Howdy folks! ( This is a C printf statement! )/n");
    return;
}


#ifdef __LCC__
/**
 * Valentin Valchev (Bulgaria, www.prosyst.com)
 * This is the standart implementation of Java 2 OnLoad and OnUnload native
 * library calls. This template defines them empty functions
 */
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)  
{
    return JNI_VERSION_1_2;
}
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)
{
}
#endif
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值