JNI点滴
来源:互联网 发布:ted速度慢 知乎 编辑:程序博客网 时间:2024/06/03 23:00
一、java通过JNI调用DLL
//MyNative.java
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来完成其实现部分。
//MyNative.h
/* 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 class mytest{
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 functionMaps 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
//MyNative.java
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来完成其实现部分。
//MyNative.h
/* 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 class mytest{
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 functionMaps 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;
}
0 0
- JNI点滴
- JNI点滴
- JNI使用技巧点滴
- JNI使用技巧点滴
- JNI使用技巧点滴
- JNI使用技巧点滴
- Android JNI 点滴
- JNI使用技巧点滴(二)
- JNI使用技巧点滴(二)
- Java进阶:JNI使用技巧点滴
- Java进阶:JNI使用技巧点滴积累
- (转)程序员进阶必读篇:JNI使用技巧点滴
- java与c/c++之间的数据交互-----jni点滴
- 点滴
- 点滴
- 点滴
- 点滴
- 点滴
- 对uC/OS-II内二维指针的研究
- git基础学习(四):工作区和暂存区
- 常用RGB颜色表
- 花生壳不在线,经常这样引起的思考及其他选择
- 程序员喝酒的计算机文化
- JNI点滴
- 关于Myeclipse不能加在已有项目的问题
- Navicat MySQL连接Linux下MySQL的问题解决方案
- Webview 不向系统浏览器跳转
- 存储过程查询 和导入导出存储过程
- C++中vector向量的基本操作
- Ajax实现无刷新任务进度条 (webform)
- 2014.04.30[论文学习]色彩及图像基础(三)
- Darwin Streaming Server for Windows 安装