windows32位上jni调用c/c++动态链接库

windows32位下jni调用c/c++动态链接库
这两天因为工作需要,组长告诉我了一个新名词jni,让我利用它用java调用c/c++的库。剩下的,就是自个百度学习去吧。我从网上也看到了好多例子,但是差不多都是转载的他人的。我根据自己的实战简单总结一下吧,有不妥之处,还望友友们指正哈~_~
第一步:在MyEclipse环境下新建一个java project工程
工程名字是jnitest,在src下面建立两个java类:
HelloWorld.java
 
public class HelloWorld {
	public native void say(String name);  //native 是java本地方法申明;native方法就是我们需要用C来实现的方法。

	public HelloWorld(){
	}//开始我没有添加这个构造函数,但是在测试类调用的时候就一直无法new 对象。所以还是加上吧。
    static {
       System.loadLibrary( "HelloWorld" ); //装入动态链接库,"HelloWorld"是要装入的动态链接库名称。就是dll文件的名字 
    }
}


TestDLL.java
public class TestDLL {
	public static void main(String[] args) {
		HelloWorld helloWorld = new HelloWorld();
		helloWorld.say("tom");//传递参数
	}
} 

第二步:编译Java类
在编写完java类之后,在工程的bin目录下回自动生成相应的class文件的。
第三步 生成C/C++头文件
在windows中打开一个命令窗口,进入jnitest工程所在目录下的bin目录如:D:\Workspaces\jnitest\bin。键入javah -classpath D:\Workspaces\jnitest\bin HelloWorld命令生成头文件HelloWorld.h。内容如下:这个文件就在 D:\Workspaces\jnitest\bin这个目录下面
HelloWorld.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloWorld
 * Method:    say
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_HelloWorld_say
  (JNIEnv *, jobject, jstring);
/**这里的jstring类型是根据HelloWorld类中的方法参数类型而自动生成的*/
#ifdef __cplusplus
}
#endif
#endif


这个h文件就不要动它啦哈!
第四步 编写本地方法实现
在这个步骤中要用到vc6工具了,我都不会用这个工具,在摸索中前进吧。不会的友友可以看一下截图。
这样工程就自动生成了cpp和h文件。
把刚才第三步生成的h文件的内容覆盖vc自动生成的h文件。
利用下面的代码覆盖vc自动生成的cpp文件:
HelloWorld.cpp
// HelloWorld.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "HelloWorld.h"
#include <stdio.h>
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
			break;
    }
    return TRUE;
}



//HelloWorld.h中函数声明相同 JNIEnv *是每个函数都有的参数, 它包含了很多有用的方法, 使用起来类似Java的反射, 也提供了这样一个编码转换的函数.
GetStringUTFChars()和NewStringUTF(), 第一个是从UTF8转换为C的编码格式, 第二个是根据C的字符串返回一个UTF8字符串.
JNIEXPORT void JNICALL Java_HelloWorld_say
 (JNIEnv *env, jobject obj, jstring instring)
{ 
//从instring字符串取得指向字符串UTF编码的指针

const jbyte *str =

        (const jbyte *)env->GetStringUTFChars( instring, JNI_FALSE );

    printf("%s say HelloWorld!/n",str);//(*env)->GetStringUTFChars()这个方法, 是用来在Java和C之间转换字符串的, 因为Java本身都使用了双字节的字符, 而C语言本身都是单字节的字符, 所以需要进行转换.

        //通知虚拟机本地代码不再需要通过str访问Java字符串。

    env->ReleaseStringUTFChars( instring, (const char *)str ); 
//ReleaseStringUTFChars()是用来释放对象的, 在Java中有虚拟机进行垃圾回收, 但是在C语言中, 这些对象必须手动回收. 否则可能造成内存泄漏.
    return;

}


然后,选中C工程HelloWorld,右键--build,如果没有错误,那么恭喜你咯,这个就通过啦!
在工程目录下面的debug文件下面会有生成的HelloWorld.dll文件。
第五步 运行测试程序
把HelloWorld.dll文件copy到java工程中引用的jdk路径bin文件下面,我的是:C:\Program Files\Genuitec\Common\binary\com.sun.java.jdk.win32.x86_1.6.0.013\jre\bin
运行测试程序,将看到控制台输出“tom say HelloWorld!/n”



据说用jni在32位的机器上可以调用c/c++库,但是在64位的上面就不可以,怎么在64位的电脑上调用c/c++库,这才是我们组长最终要我解决的问题。如果有哪位高人知道的话,麻烦给俺指点一下哈~~