相关链接(Java Native Interface Specification-jdk1.6和实例 CHM)
添加系统变量
JAVA_HOME="C:/Program Files/Java/jdk1.6.0_02"
在CLASSPATH中添加如下内容,如果没有CLASSPATH则需要新建系统变量
CLASSPATH=".;%JAVA_HOME%/lib;"
PATH添加如下内容,如果没有path则需要新建系统变量
path="%JAVA_HOME%/bin;"(一定要将其写在最前面,如果不写在最前面会优先搜索到其他的java版本)
javah命令使用
利用eclipse编写程序,在build下面的class放的是编译完成的.class文件。
在开始--运行输入cmd进入控制台,cd到classes目录下
执行javah命令,注意如果要生成的文件在开头有package *.*.*;
则javah命令如下
javah -jni *.*.*.文件名( *.*.*为package名称)否则不能正常执行命令
当然如果没有package的话直接运行javah 文件名就可以
编译成功之后形成以保名称和类名组成的文件名称格式,形如
edu_bjut_bjwater_test.h
利用vc6.0编程实现dll方法
选择new->projects(选择Win32 Dynamic-Link Library)
选择Tools->Options->Directories 添加如下include路径
C:/PROGRAM FILES/JAVA/JDK1.6.0_02/INCLUDE
C:/PROGRAM FILES/JAVA/JDK1.6.0_02/INCLUDE/win32
根据具体的jdk安装路径添加include文件
将上面生成的.h文件拷贝到工程中,新建**.cpp文件以实现相应的功能
具体文件内容如下
***************************************************************
#include "edu_bjut_bjwater_pub_TestJNI.h"
JNIEXPORT jint JNICALL Java_edu_bjut_bjwater_pub_TestJNI_add
(JNIEnv *, jobject, jint x, jint y)
{
return (x+y);
}
****************************************************************
然后编译生成**.dll文件
JAVA程序完成对dll文件的使用
static {
System.loadLibrary("jni"); (1)
}
public native int add(int x,int y); (2)
注意:(1)中使用loadLibraty()函数对dll文件调用,在这里有两个需要明确注意的问题1.这个函数加载的路径是java.library.path,在这个路径下搜索jni.dll,那么到底这个java.library.path路径是什么呢?经过打印发现其实就是系统变量中设置的PATH,所以我们可以将dll文件中拷贝到PATH中的路径下,就可以找到dll文件了,还有一个办法是通过jvm设置这个路径,
-Djava.library.path="D:/eclipse_workspace/db2pool/build/classes/dll"
这样程序就到仅仅到要求的路径下找需要的dll文件,如果还有其他的访问java.library.path程序可能会出现错误,所以不建议使用这种方法,其实我们可以设置path系统变量,将dll文件的路径设置成系统变量,就可以增加它的搜索范围,不至于使其他的程序不能正常的执行.重要说明的是,当设置path环境变量之后,要重新启动eclipse,因为在启动eclipse是java虚拟机读入path,是不可更改的。
2.loadlibrary()参数我们只需要写名字就可以,不用写jni.dll,因为它会自动去找那个名字的文件,不需要我们指定dll,否则会运行错误。
(2)中声明native函数,所以是在先写这个java程序,然后在生成的.h文件,在编写相应的dll文件
编写操作系统用户程序
menu:project ->Settings dialog
link tab
Object/library modules: add the following library
Netapi32.lib
否则编译出错
error LNK2001: unresolved external symbol _NetUserEnum@32
生成relese版本dll,通用操作build->set active configuration->*** win32 relese
***************************************************************
总结
LPCSTR/LPSTR/LPCTSTR/LPTSTR/LPCWSTR/LPWSTR/
首先先说一下VC中这几个代表的是什么意思
P----pointer
C----const
在
typedef unsigned short wchar_t
LPSTR/PSTR --- char *
LPCSTR/PCSTR --- const char *
LPSTR被定义成是一个指向以NULL('/0')结尾的8位ANSI字符数组指针.
在winnt.h中看到这样一段定义
#ifdef UNICODE
typedef LPWSTR LPTSTR;
typedef LPCWSTR LPCTSTR;
#else
typedef LPSTR LPTSTR;
typedef LPCSTR LPCTSTR;
#endif
也就是说如果define UNICODE的话LPTSTR与LPWSTR的意思是一样的,否则的话LPTSTR的意思与LPSTR的意思是一样的。那么下面我们在看看LPWSTR是怎么定义的?
LPWSTR ----- unsigned short *
LPCWSTR----- const unsigned short *
LPWSTR是一个指向以NULL结尾的16位双字节字符数组指针.
其次讲一下他们之间的相互转化
LPSTR <--->LPCSTR 可以用strcpy()函数完成此功能,将LPCSTR赋值给LPSTR
LPTSTR <--->LPCTST 可以用wcscpy()函数完成此功能,LPCTST->LPTSTR
LPWSTR -->char *
LPWSTR pwz = "some text";
char* psz = new char [wcslen(pwsz) + 1];
wsprintfA ( psz, "%S", pwsz);
The "%S" will implicitly convert UNICODE to ANSI.
LPWSTR <--char *
char* psz = "some text";
wchar_t* pwsz = new wchar_t [strlen(psz) + 1];
wsprintfW ( pwsz, L"%S", psz);
PTSTR转换为PSTR是个编码转换问题。
编码转换可以用MS的函数完成。
WideCharToMultiByte将unicode转换成ascii
MultiByteToWideChar将ascii转换成unicode