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

这两天因为工作需要,组长告诉我了一个新名词jni,让我利用它用java调用c/c++的库。剩下的,就是自个百度学习去吧。我从网上也看到了好多例子,但是差不多都是转载的他人的。我根据自己的实战简单总结一下吧,有不妥之处,还望友友们指正哈~_~
[color=red][b]第一步:在MyEclipse环境下新建一个java project工程[/b][/color]
工程名字是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");//传递参数
}
}

[b][color=red]第二步:编译Java类[/color][/b]
在编写完java类之后,在工程的bin目录下回自动生成相应的class文件的。
[color=red][b]第三步 生成C/C++头文件[/b][/color]
在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文件就不要动它啦哈!
[b][color=red]第四步 编写本地方法实现 [/color][/b]
在这个步骤中要用到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”


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值