一般,指定JVM的native library路径,只需要用下面的参数就好了
-Djava.library.path=PATH_TO_NATIVE_LIBRARY
Tomcat指定native library路径时,还是不要使用这边参数的好。
建议直接修改PATH环境变量,将dll或so放到环境变量PATH的路径下就好了。
TOMCAT默认将PATH赋值给-Djava.library.path参数的。
Learn and share.
一般,指定JVM的native library路径,只需要用下面的参数就好了
-Djava.library.path=PATH_TO_NATIVE_LIBRARY
Tomcat指定native library路径时,还是不要使用这边参数的好。
建议直接修改PATH环境变量,将dll或so放到环境变量PATH的路径下就好了。
TOMCAT默认将PATH赋值给-Djava.library.path参数的。
最近又用jni写了一个编码工具,从中抽出了最简单的代码,如下:
1、Compress4j.java
package com.neohope.test.compress.jni;
/**
*
* @author Hansen
*/
public class Compress4j {
private native int encodeR(String inFilePath,String outFilePaht);
private native int decodeR(String inFilePath,String outFilePaht);
static{
try{
System.loadLibrary("compress4j");
}catch(UnsatisfiedLinkError e){
//nothing to do
System.out.println("Error: Couldn't load compress4j");
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public String encode(String inFilePath,String outFilePath)
{
encodeR(inFilePath, outFilePath);
return "xxxxx";
}
public String decode(String inFilePath,String outFilePath)
{
decodeR(inFilePath, outFilePath);
return "xxxxx";
}
}
2、找到生成的classes文件夹,运行命令行:
javah -classpath . -jni com.neohope.test.compress.jni.Compress4j
3、生成的.h文件如下
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_neohoe_test_compress_jni_Compress4j */
#ifndef _Included_com_neohoe_test_compress_jni_Compress4j
#define _Included_com_neohoe_test_compress_jni_Compress4j
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_neohoe_test_compress_jni_Compress4j
* Method: encodeR
* Signature: (Ljava/lang/String;Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_com_neohoe_test_compress_jni_Compress4j_encodeR
(JNIEnv *, jobject, jstring, jstring);
/*
* Class: com_neohoe_test_compress_jni_Compress4j
* Method: decodeR
* Signature: (Ljava/lang/String;Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_com_neohoe_test_compress_jni_Compress4j_decodeR
(JNIEnv *, jobject, jstring, jstring);
#ifdef __cplusplus
}
#endif
#endif
3、编写成的.cc文件如下
#include "com_neohoe_test_compress_jni_Compress4j.h"
JNIEXPORT jint JNICALL Java_com_neohoe_test_compress_jni_Compress4j_encodeR
(JNIEnv *env, jobject, jstring inpathjs, jstring outpathjs)
{
//first convert jstring to const char*
const char* inpath = env->GetStringUTFChars( inpathjs, false);
const char* outpath = env->GetStringUTFChars( outpathjs, false);
//...
return 0;
}
JNIEXPORT jint JNICALL Java_com_neohoe_test_compress_jni_Compress4j_decodeR
(JNIEnv *env, jobject, jstring inpathjs, jstring outpathjs)
{
//first convert jstring to const char*
const char* inpath = env->GetStringUTFChars( inpathjs, false);
const char* outpath = env->GetStringUTFChars( outpathjs, false);
//...
return 0;
}
4、在VS工程中,新增头文件目录
%JAVA_HOME%/include
%JAVA_HOME%/include/win32
5、编译为dll即可使用啦
6、关于mt和md的问题
编译为MT和MTd的话,用JNI是没有任何问题的
编译为MD的话,需要安装VC2010sp1可再发行包
编译为MDd的话,就比较麻烦了,手动复制依赖的dll后,我用c++调用dll可以成功,但用jni就一直提示:缺少依赖的dll
1.Java代码CallApi.java
class CallApi{
private native String showMessageBox(String msg);
private native double getRandomDouble();
static{
try{
System.loadLibrary("CallApi");
System.out.println("Loaded CallApi");
}catch(UnsatisfiedLinkError e){
//nothing to do
System.out.println("Couldn't load CallApi");
System.out.println(e.getMessage());
}
}
public static void main(String args[]){
CallApi api = new CallApi();
double randomNumber = api.getRandomDouble();
String retval = api.showMessageBox("Hello from Java!\n"+
"The native random number: "+randomNumber);
System.out.println("The native string: "+retval);
}
}
2.生成dll的CallApi.h文件
javah -classpath . -jni CallApi
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class CallApi */
#ifndef _Included_CallApi
#define _Included_CallApi
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: CallApi
* Method: showMessageBox
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_CallApi_showMessageBox
(JNIEnv *, jobject, jstring);
/*
* Class: CallApi
* Method: getRandomDouble
* Signature: ()D
*/
JNIEXPORT jdouble JNICALL Java_CallApi_getRandomDouble
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
3.手写dll的CallApi.c文件
#include"CallApi.h"
#include <windows.h>
#include <time.h>
//#pragma comment(lib,"user32.lib")
JNIEXPORT jstring JNICALL Java_CallApi_showMessageBox
(JNIEnv *env, jobject thisObject, jstring js)
{
//first convert jstring to const char for use in MessageBox
const jbyte* argvv = (*env)->GetStringUTFChars(env, js, NULL);
char* argv =(char *) argvv;
//Call MessageBoxA
MessageBox(NULL, argv, "Called from Java!", MB_ICONEXCLAMATION | MB_OK);
return js;
}
JNIEXPORT jdouble JNICALL Java_CallApi_getRandomDouble
(JNIEnv *env, jobject thisObject)
{
double num1;
srand((unsigned)(time(0)));
num1 = ((double)rand()/(double)RAND_MAX);
return num1;
}
4.编译
注意1:要引用jdk下的include目录下文件,因此要增加引用文件路径
注意2:用MT而不是MD
5.运行
java -Djava.library.path=. CallApi