JNI之Helloworld
问题背景:由于最近生活轻松,毕设刚刚紧张起来,音频检索的代码全部是C/C++编写的,而B/S平台的应有要搭建服务器,我只会J2EE/JSP那些东东,所以要学会JNI调C/C++代码。
下面介绍下如何构建自己第一个JNI程序。
(1) 将%JAVA_HOME%下的include文件夹的jni.h等等所有的头文件拷贝到VC IDE下面的Include目录下。
(2) 编写Printf.java类
public class Printf { // 导入动态链接库,这个库是用cl.exe或者直接用VC生存的。 static { System.loadLibrary("HelloNative3.dll"); } // 最简单的打印“Helloworld”的方法 public native static void greeting(); // 传递字符串实验方法 public native static String sprint(String str); } |
(3) 编译上面Printf类,在cmd输入 javah Printf。生成了Printf.h头文件
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class Printf */ #ifndef _Included_Printf #define _Included_Printf #ifdef __cplusplus extern "C" { #endif /* * Class: Printf * Method: greeting * Signature: ()V */ JNIEXPORT void JNICALL Java_Printf_greeting (JNIEnv *, jclass); /* * Class: Printf * Method: sprint * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_Printf_sprint (JNIEnv *, jclass, jstring); #ifdef __cplusplus } #endif #endif |
(4) 打开VC IDE新建DLL工程。
新建HelloNative.cpp,编译如果出现错误尝试把(env *)改为(env) 或者 改文件名为HelloNative.c
#include <stdio.h> #include "Printf.h" #include <jni.h> #include <string.h> #include <stdlib.h> #include <windows.h> char* jstringToWindows( JNIEnv *env, jstring jstr ); jstring WindowsTojstring( JNIEnv* env, char* str ); JNIEXPORT void JNICALL Java_Printf_greeting(JNIEnv * env, jclass cl) { printf("hello, Native World!\n"); } char* searchMusic(const char music_path[]) { char* music_info = "这里显示的是音乐的具体信息,该参数应有其他函数返回"; return music_info; } JNIEXPORT jstring JNICALL Java_Printf_sprint(JNIEnv * env, jclass cl, jstring j_str) { const char* c_str; char* c_res; jstring j_res; <strong><em> // 用以下方法中文出现乱码</em> // c_str = (*env)->GetStringUTFChars(env,j_str,NULL); c_str = jstringToWindows( env, j_str );</strong> printf("%s\n",c_str); c_res = searchMusic(c_str); <strong> j_res = WindowsTojstring(env ,c_res);</strong> <strong><em> // 用以下方法中文出现乱码</em> // j_res = (*env)->NewStringUTF(env,c_res);</strong> (*env)->ReleaseStringUTFChars(env,j_str,c_str); return j_res; } // 从Java传递过来的字符串参数转化为C能读懂的中文char char* jstringToWindows( JNIEnv *env, jstring jstr ) { int length = (*env)->GetStringLength(env,jstr ); const jchar* jcstr = (*env)->GetStringChars(env,jstr, 0 ); char* rtn = (char*)malloc( length*2+1 ); int size = 0; size = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)jcstr, length, rtn,(length*2+1), NULL, NULL ); if( size <= 0 ) return NULL; (*env)->ReleaseStringChars(env,jstr, jcstr ); rtn[size] = 0; return rtn; } // C处理返回的字符串转化为中文 jstring WindowsTojstring( JNIEnv* env, char* str ) { jstring rtn = 0; int slen = strlen(str); unsigned short* buffer = 0; if( slen == 0 ) rtn = (*env)->NewStringUTF(env,str ); else { int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, NULL, 0 ); buffer = malloc( length*2 + 1 ); if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length ) >0 ) rtn = (*env)->NewString( env, (jchar*)buffer, length ); } if( buffer ) free( buffer ); return rtn; } |
(5) 在VC中生成HelloNative.dll 拷贝到System32下面。
(6) 测试Java类
public class HelloNativeTest { public static void main(String[] args) throws Exception { Printf.greeting(); String music_utf = Printf.sprint("F:\\中文音乐"); System.out.println( music_utf ); } } |
好详细!哈哈这个我也做过
帮着补充个边边角角,那个dll只放在环境变量能搜到的地方都可以,Windows目录,我还曾经放过Java的bin目录里~
哈哈 这个我还是毕业前作的 记不得了都 总之放很多地方总会找的到的。。。