标签:jni
一、java通过JNI调用DLL
public class MyNative{
static{
System.loadLibrary("MyNative");
}
public native static void HelloWorld();
public native String cToJava();
}
本地方法(native)是否为静态方法(static),所产生的C函数参加类型是jclass 或jobject.
通过命令javac MyNative.java生成MyNative.class文件;然后javah MyNative生成MyNative.h头文件。
余下的工作交给VC来完成其实现部分。
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class MyNative */
#ifndef _Included_MyNative
#define _Included_MyNative
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: MyNative
* Method: HelloWorld
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_MyNative_HelloWorld
(JNIEnv *, jclass);
/*
* Class: MyNative
* Method: cToJava
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_MyNative_cToJava
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
上面两个函数的实现在具体的工程中完成,通过创建DLL工程,新建MyNative.cpp文件,
//MyNative.cpp工程属性设置包含JDK目录中include子目录
#include <stdio.h>
#include "MyNative.h"
JNIEXPORT void JNICALL Java_MyNative_HelloWorld
(JNIEnv *, jclass){
printf("Hello World 你好中国");
}
JNIEXPORT jstring JNICALL Java_MyNative_cToJava
(JNIEnv *env, jobject obj){
jstring jstr;
char str[]="Hello 美国\n";
jstr=env->NewStringUTF(str);
return jstr;
}
测试所写的DLL文件所用java类:
public static void main(String args[]){
MyNative a= new MyNative();
a.HelloWorld();
System.out.println(a.cToJava());
}
}
假如jni.h头文件没有修改,上述a.cToJava()方法打印出的信息会出现乱码。
即“美国”出现乱码,修改NewStringUTF方法。
下面具体分析jni.h头文件涉及的函数及知识点
const jchar *GetStringChars(jstring str, jboolean *isCopy) {
return functions->GetStringChars(this,str,isCopy);
}
返回 Unicode字符串,类型jchar占用2字节。
NewStringUTF根据Native的一个UTF-8字符串得到一个Jstring对象,
修改NewStringUTF方法如下:
jstring NewStringUTF(const char *utf) {
jstring rtn = 0;
int slen = strlen(utf);
unsigned short * buffer = 0;
if( slen == 0 )
rtn = functions->NewStringUTF(this,utf );
else
{
int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)utf, slen, NULL, 0 );
buffer = (unsigned short *)malloc( length*2 + 1 );
if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)utf, slen, (LPWSTR)buffer, length ) >0 )
rtn = functions->NewString(this,(jchar*)buffer, length );
}
if( buffer )
free( buffer );
return rtn;
//return functions->NewStringUTF(this,utf);
}
[多字节与宽字节转换]
MultiByteToWideChar function
Maps a character string to a UTF-16 (wide character) string.
int MultiByteToWideChar(
_In_ UINT CodePage,
_In_ DWORD dwFlags,
_In_ LPCSTR lpMultiByteStr,
_In_ int cbMultiByte,
_Out_opt_ LPWSTR lpWideCharStr,
_In_ int cchWideChar
);
代码页由CP_ACP和CP_UTF8
//ANSI to Unicode
wstring ANSIToUnicode( const string& str )
{
int len = 0;
len = str.length();
int unicodeLen = ::MultiByteToWideChar( CP_ACP,0,str.c_str(),-1,NULL,0 );
wchar_t * pUnicode;
pUnicode = new wchar_t[unicodeLen+1];
memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t));
::MultiByteToWideChar( CP_ACP,0,str.c_str(),-1,(LPWSTR)pUnicode,unicodeLen );
wstring rt;
rt = ( wchar_t* )pUnicode;
delete pUnicode;
return rt;
}
//Unicode to ANSI
string UnicodeToANSI( const wstring& str )
{
char* pElementText;
int iTextLen;
// wide char to multi char
iTextLen = WideCharToMultiByte( CP_ACP,
0,
str.c_str(),
-1,
NULL,
0,
NULL,
NULL );
pElementText = new char[iTextLen + 1];
memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) );
::WideCharToMultiByte( CP_ACP,
0,
str.c_str(),
-1,
pElementText,
iTextLen,
NULL,
NULL );
string strText;
strText = pElementText;
delete[] pElementText;
return strText;
}
//UTF-8 to Unicode
wstring UTF8ToUnicode( const string& str )
{
int len = 0;
len = str.length();
int unicodeLen = ::MultiByteToWideChar( CP_UTF8,0,str.c_str(),-1,NULL,0 );
wchar_t * pUnicode;
pUnicode = new wchar_t[unicodeLen+1];
memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t));
::MultiByteToWideChar( CP_UTF8,0,str.c_str(),-1,(LPWSTR)pUnicode,unicodeLen );
wstring rt;
rt = ( wchar_t* )pUnicode;
delete pUnicode;
return rt;
}
//Unicode to UTF-8
string UnicodeToUTF8( const wstring& str )
{
char* pElementText;
int iTextLen;
// wide char to multi char
iTextLen = WideCharToMultiByte( CP_UTF8,0,str.c_str(),-1,NULL,0,NULL,NULL );
pElementText = new char[iTextLen + 1];
memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) );
::WideCharToMultiByte( CP_UTF8,0,str.c_str(),-1,pElementText,iTextLen,NULL,NULL );
string strText;
strText = pElementText;
delete[] pElementText;
return strText;
}
一、java通过JNI调用DLL
public class MyNative{
static{
System.loadLibrary("MyNative");
}
public native static void HelloWorld();
public native String cToJava();
}
本地方法(native)是否为静态方法(static),所产生的C函数参加类型是jclass 或jobject.
通过命令javac MyNative.java生成MyNative.class文件;然后javah MyNative生成MyNative.h头文件。
余下的工作交给VC来完成其实现部分。
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class MyNative */
#ifndef _Included_MyNative
#define _Included_MyNative
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: MyNative
* Method: HelloWorld
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_MyNative_HelloWorld
(JNIEnv *, jclass);
/*
* Class: MyNative
* Method: cToJava
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_MyNative_cToJava
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
上面两个函数的实现在具体的工程中完成,通过创建DLL工程,新建MyNative.cpp文件,
//MyNative.cpp工程属性设置包含JDK目录中include子目录
#include <stdio.h>
#include "MyNative.h"
JNIEXPORT void JNICALL Java_MyNative_HelloWorld
(JNIEnv *, jclass){
printf("Hello World 你好中国");
}
JNIEXPORT jstring JNICALL Java_MyNative_cToJava
(JNIEnv *env, jobject obj){
jstring jstr;
char str[]="Hello 美国\n";
jstr=env->NewStringUTF(str);
return jstr;
}
测试所写的DLL文件所用java类:
public static void main(String args[]){
MyNative a= new MyNative();
a.HelloWorld();
System.out.println(a.cToJava());
}
}
假如jni.h头文件没有修改,上述a.cToJava()方法打印出的信息会出现乱码。
即“美国”出现乱码,修改NewStringUTF方法。
下面具体分析jni.h头文件涉及的函数及知识点
const jchar *GetStringChars(jstring str, jboolean *isCopy) {
return functions->GetStringChars(this,str,isCopy);
}
返回 Unicode字符串,类型jchar占用2字节。
NewStringUTF根据Native的一个UTF-8字符串得到一个Jstring对象,
修改NewStringUTF方法如下:
jstring NewStringUTF(const char *utf) {
jstring rtn = 0;
int slen = strlen(utf);
unsigned short * buffer = 0;
if( slen == 0 )
rtn = functions->NewStringUTF(this,utf );
else
{
int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)utf, slen, NULL, 0 );
buffer = (unsigned short *)malloc( length*2 + 1 );
if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)utf, slen, (LPWSTR)buffer, length ) >0 )
rtn = functions->NewString(this,(jchar*)buffer, length );
}
if( buffer )
free( buffer );
return rtn;
//return functions->NewStringUTF(this,utf);
}
[多字节与宽字节转换]
MultiByteToWideChar function
Maps a character string to a UTF-16 (wide character) string.
int MultiByteToWideChar(
_In_ UINT CodePage,
_In_ DWORD dwFlags,
_In_ LPCSTR lpMultiByteStr,
_In_ int cbMultiByte,
_Out_opt_ LPWSTR lpWideCharStr,
_In_ int cchWideChar
);
代码页由CP_ACP和CP_UTF8
//ANSI to Unicode
wstring ANSIToUnicode( const string& str )
{
int len = 0;
len = str.length();
int unicodeLen = ::MultiByteToWideChar( CP_ACP,0,str.c_str(),-1,NULL,0 );
wchar_t * pUnicode;
pUnicode = new wchar_t[unicodeLen+1];
memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t));
::MultiByteToWideChar( CP_ACP,0,str.c_str(),-1,(LPWSTR)pUnicode,unicodeLen );
wstring rt;
rt = ( wchar_t* )pUnicode;
delete pUnicode;
return rt;
}
//Unicode to ANSI
string UnicodeToANSI( const wstring& str )
{
char* pElementText;
int iTextLen;
// wide char to multi char
iTextLen = WideCharToMultiByte( CP_ACP,
0,
str.c_str(),
-1,
NULL,
0,
NULL,
NULL );
pElementText = new char[iTextLen + 1];
memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) );
::WideCharToMultiByte( CP_ACP,
0,
str.c_str(),
-1,
pElementText,
iTextLen,
NULL,
NULL );
string strText;
strText = pElementText;
delete[] pElementText;
return strText;
}
//UTF-8 to Unicode
wstring UTF8ToUnicode( const string& str )
{
int len = 0;
len = str.length();
int unicodeLen = ::MultiByteToWideChar( CP_UTF8,0,str.c_str(),-1,NULL,0 );
wchar_t * pUnicode;
pUnicode = new wchar_t[unicodeLen+1];
memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t));
::MultiByteToWideChar( CP_UTF8,0,str.c_str(),-1,(LPWSTR)pUnicode,unicodeLen );
wstring rt;
rt = ( wchar_t* )pUnicode;
delete pUnicode;
return rt;
}
//Unicode to UTF-8
string UnicodeToUTF8( const wstring& str )
{
char* pElementText;
int iTextLen;
// wide char to multi char
iTextLen = WideCharToMultiByte( CP_UTF8,0,str.c_str(),-1,NULL,0,NULL,NULL );
pElementText = new char[iTextLen + 1];
memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) );
::WideCharToMultiByte( CP_UTF8,0,str.c_str(),-1,pElementText,iTextLen,NULL,NULL );
string strText;
strText = pElementText;
delete[] pElementText;
return strText;
}
JNI点滴
标签:jni
原文地址:http://blog.csdn.net/makamus/article/details/24783793