欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
JNI之C++調用Java類(lèi) —— java.lang.String
 

    為什么要用C++調用Java類(lèi)?很難回答,寫(xiě)著(zhù)文章只是覺(jué)得JNI很有意思。于是開(kāi)始編寫(xiě)一段使用VC++在Windows系統里調用java的 String類(lèi),在C++里調用String類(lèi)內的一些方法。

    JNI已經(jīng)被開(kāi)發(fā)了很多年,而在我2年多的Java編程時(shí)間里從來(lái)沒(méi)有接觸過(guò)。直到最近研究JVM實(shí)現原理才注意到JNI。 JNI既Java Native Interface,Native這個(gè)詞我見(jiàn)過(guò)我認為最恰當的翻譯就是原生。原生的意思就是來(lái)自系統自己的,原汁原味的東西,例如Win32 API。Java類(lèi)需要在虛擬機上運行,也就不是原生的,同樣.NET Framework也不是原生的。JNI也就是Java原生接口。關(guān)于JNI的規范,以及為什么要使用它,它能做些什么,都在http://java.sun.com/j2se/1.4.2/docs/guide/jni/spec/jniTOC.html里記述著(zhù)。

    JNI是規范,它規定了虛擬機的接口,而把具體的實(shí)現留給開(kāi)發(fā)者。

    JVM的實(shí)現不是唯一的,目前存在很多種Java虛擬機,Sun Hotspot,IBM JDK,還有HP的,Kaffe等等。最流行的就是Sun的Hotspot,最復雜的就是IBM JDK,這是IBM的一貫作風(fēng)。本文不討論JVM的實(shí)現,只關(guān)注JNI。如果您安裝了Sun的JDK,您就能在[JAVA_HOME]\include目錄下找到j(luò )ni.h。這個(gè)頭文件就是虛擬機的唯一接口,你可以調用它聲明的函數創(chuàng )建一個(gè)JVM。

    在說(shuō)明C++調用Java類(lèi)之前,我想先演示一下如果編寫(xiě)Java Native Method。

1.編寫(xiě)帶有Native方法的Java類(lèi)

package org.colimas.jni.test;

public class JniTest {

    
static { System.loadLibrary("JniTestImpl"); }  //JVM調用JniTestImpl.dll

    
public JniTest(){
    }


    
//原生方法
    public native void print(String str);

    
/**
    * 
@param args
    
*/

    
public static void main(String[] args) {
            JniTest test
=new JniTest();
            test.print(
"hello JVM"); //調用原生方法
    }

}

2.使用javah生成c語(yǔ)言頭文件。 

javah -jni org.colimas.jni.test.JniTest

目錄里多了一個(gè)org_colimas_jni_test_JniTest.h文件,打開(kāi)文件,內容如下: 

/* DO NOT EDIT THIS FILE - it is machine generated */

#include 
<jni.h>

/* Header for class org_colimas_jni_test_JniTest */


#ifndef _Included_org_colimas_jni_test_JniTest
#define _Included_org_colimas_jni_test_JniTest
#ifdef __cplusplus

extern "C" {

#endif

/*
 * Class:     org_colimas_jni_test_JniTest
 * Method:    print
 * Signature: (Ljava/lang/String;)V
 
*/


JNIEXPORT 
void JNICALL Java_org_colimas_jni_test_JniTest_print
  (JNIEnv 
*, jobject, jstring);

#ifdef __cplusplus
}


#endif
#endif

其中的Java_org_colimas_jni_test_JniTest_print就是JniTest類(lèi)里面的print原生方法的C語(yǔ)言聲明。

3.編寫(xiě)C代碼實(shí)現原生方法print 

#include <jni.h>
#include 
"org_colimas_jni_test_JniTest.h" //javah生成的頭文件
#include <stdio.h>

JNIEXPORT 
void JNICALL Java_org_colimas_jni_test_JniTest_print
  (JNIEnv 
*env, jobject object,jstring str)
{
       
//獲得字符串
       const char * txt=(*env)->GetStringUTFChars(env,str,0);
       printf(
"%s ",txt); //打印到控制臺
       return;
}

參數JNIEnv *env,是JNI里最重要的變量。Java.exe創(chuàng )建JVM,之后JVM生成一個(gè)env,該env相當于JVM內的Session,可以完成創(chuàng )建 Java對象,調用類(lèi)方法,獲得類(lèi)的屬性等等。

在這里env將方法的參數Str從JNI的jstring類(lèi)型轉換為常數char數組。

4.編譯 

cl  /Ic:j2sdk1.4.2_10include /Ic:j2sdk1.4.2_10includewin32 /c  JniTestImpl.c

5.連接為DLL

link /dll JniTestImpl.obj

6.設置PATH

set PATH=C:MyProjectColimasCDJNIMyJNI;%PATH%

7.運行

java org.colimas.jni.test.JniTest

返回結果

hello JVM

結束

    以上是實(shí)現Java原生方法的開(kāi)發(fā)過(guò)程,下面進(jìn)入正題,使用C++調用Java的java.lang.String類(lèi)。

1. Object類(lèi)出創(chuàng )建JVM。

使用Java類(lèi)之前必須要創(chuàng )建JVM環(huán)境。JDK由java.exe來(lái)完成。本文有Object類(lèi)的靜態(tài)方法BeginJVM來(lái)創(chuàng )建,用 EndJVM來(lái)關(guān)閉。

創(chuàng )建JVM之后會(huì )在創(chuàng )建2個(gè)變量,分別是JNIEnv* env和JavaVM* jvm,JNIEnv上文已經(jīng)說(shuō)明,JavaVM,顧名思義,代表Java虛擬機,用它來(lái)關(guān)閉JVM。

Object類(lèi)的頭文件 

#include "jni.h"

class Object
{
public:
    
static bool BeginJVM();
    
static bool EndJVM();
    Object();
    
virtual ~Object();

protected:
    
static JNIEnv* env;
    
static JavaVM* jvm;
}
;

object.cpp代碼 

#include "stdafx.h"
#include 
"JavaClasses.h"
#include 
"Object.h"

Object::Object()
{}

Object::
~Object()
{}

JNIEnv
* Object::env=NULL;
JavaVM
* Object::jvm=NULL;

//創(chuàng )建JVM

bool Object::BeginJVM()
{

    JavaVMOption options[
3];
    JavaVMInitArgs vm_args;

    
//各種參數
    options[0].optionString="-Xmx128m";
    options[
1].optionString="-Verbose:gc";
    options[
2].optionString="-Djava.class.path=.";

    vm_args.version
=JNI_VERSION_1_2;
    vm_args.options
=options;
    vm_args.nOptions
=3;

    
//創(chuàng )建JVM,獲得jvm和env
    int res = JNI_CreateJavaVM(&jvm,(void **)&env, &vm_args);
    
return true;
}


bool Object::EndJVM()
{
    
//關(guān)閉JVM
    jvm->DestroyJavaVM();
    
return true;
}

2. C++的String類(lèi)調用java.lang.String類(lèi)方法

編寫(xiě)C++版的String類(lèi),調用java String類(lèi)方法。調用的方法如下:

    String  replaceAll(String regex, String replacement);

    boolean endsWith(String str);

    
int indexOf(String str);

    
int compareTo(String anotherString);

    
char charAt(int i);

String的頭文件:

class String  :public Object
{
public:
//與要調用的Java方法名一致。
    const char * replaceAll(char *regex,char *replacement);

    
bool endsWith(char * str);

    
int indexOf(char * str);

    
int compareTo(char *anotherString);

    
char charAt(int i);

    String(
char *str);

    
virtual ~String();
}
;

實(shí)現: 

#include "stdafx.h"
#include 
"String.h"
#include 
"jni.h"

using namespace std;

jclass clazz;    
//全局變量,用來(lái)傳遞class
jobject object;  //全局變量,用來(lái)傳遞object
String::String(char *str)
{
    jstring jstr;

    
if (Object::env ==NULL){
        cout 
<< "JVM is not created" << endl;
        exit(
-1);
    }


    
//獲得java.lang.String類(lèi)
    clazz=Object::env->FindClass("java/lang/String");

    
if (clazz ==0 ){
        cout 
<< "Class is not found" << endl;
        exit(
-1);
    }


    
//獲得String(String str)構造體
    jmethodID mid= Object::env->GetMethodID(clazz,"<init>""(Ljava/lang/String;)V");

    
if (mid==0){
        cerr
<< "GetMethodID Error for class" << endl;
        exit(
-1);
    }


    
//將字符串封裝為jstring。
    jstr = Object::env->NewStringUTF(str);

    
if (jstr == 0{
        cerr 
<< "Out of memory" <<endl;
        exit(
-1);
    }


    cout 
<< "invoking method" << endl;

    
//創(chuàng )建一個(gè)java.lang.String對象。
    object=Object::env->NewObject(clazz,mid,jstr);
}


String::
~String()
{}

char String::charAt(int i)
{
    
if (Object::env ==NULL){
        cout 
<< "JVM is not created" << endl;
        exit(
-1);
    }


    
if (clazz ==0 ){
        cout 
<< "Class is not found" << endl;
        exit(
-1);
    }


    
if (object ==0 ){
        cout 
<< "String object is not created" << endl;
        exit(
-1);
    }


    jmethodID mid;

    
//獲得charAt方法,(I)C表示 參數為int型,返回char型。詳細參見(jiàn) JNI規范
    mid = Object::env->GetMethodID(clazz,"charAt""(I)C");

    
if (mid==0){
        cerr
<< "GetMethodID Error for class" << endl;
        exit(
-1);
    }


    jint ji
=i;

    cout 
<< "invoking method" << endl;

    
//調用charAt
    jchar z = Object::env->CallCharMethod(object,mid,i);

    
//返回結果。
    return z;
}



int String::compareTo(char *anotherString)
{

    
if (Object::env ==NULL){
        cout 
<< "JVM is not created" << endl;
        exit(
-1);
    }


    
if (clazz ==0 ){
        cout 
<< "Class is not found" << endl;
        exit(
-1);
    }


    
if (object ==0 ){
        cout 
<< "String object is not created" << endl;
        exit(
-1);
    }


    jmethodID mid;

    
//(Ljava/lang/String;)I表示參數為 java.lang.String,返回int
    mid= Object::env->GetMethodID(clazz,"compareTo""(Ljava/lang/String;)I");

    
if (mid==0){
        cerr
<< "GetMethodID Error for class" << endl;
        exit(
-1);
    }


    jstring jstr 
= Object::env->NewStringUTF(anotherString);
    cout 
<< "invoking method" << endl;

    
//調用方法
    jint z=Object::env->CallIntMethod(object,mid,jstr);

    
//返回結果
    return z;
}



int String::indexOf(char *str)
{
    
if (Object::env ==NULL){
        cout 
<< "JVM is not created" << endl;
        exit(
-1);
    }


    
if (clazz ==0 ){
        cout 
<< "Class is not found" << endl;
        exit(
-1);
    }


    
if (object ==0 ){
        cout 
<< "String object is not created" << endl;
        exit(
-1);
    }


    jmethodID mid;
    mid
= Object::env->GetMethodID(clazz,"indexOf""(Ljava/lang/String;)I");

    
if (mid==0){
        cerr
<< "GetMethodID Error for class" << endl;
        exit(
-1);
    }


    jstring jstr 
= Object::env->NewStringUTF(str);
    cout 
<< "invoking method" << endl;

    jint z
=Object::env->CallIntMethod(object,mid,jstr);
    
return z;
}



bool String::endsWith(char *str)
{

    
if (Object::env ==NULL){
        cout 
<< "JVM is not created" << endl;
        exit(
-1);
    }


    
if (clazz ==0 ){
        cout 
<< "Class is not found" << endl;
        exit(
-1);
    }


    
if (object ==0 ){
        cout 
<< "String object is not created" << endl;
        exit(
-1);
    }


    jmethodID mid;
    mid
= Object::env->GetMethodID(clazz,"endsWith""(Ljava/lang/String;)Z");

    
if (mid==0){
        cerr
<< "GetMethodID Error for class" << endl;
        exit(
-1);
    }


    jstring jstr 
= Object::env->NewStringUTF(str);
    cout 
<< "invoking method" << endl;

    
bool z = Object::env->CallBooleanMethod(object,mid,jstr);
    
return z;
}



const char * String::replaceAll(char *regex, char *replacement)
{
    
if (Object::env ==NULL){
        cout 
<< "JVM is not created" << endl;
        exit(
-1);
    }


    
if (clazz ==0 ){
        cout 
<< "Class is not found" << endl;
        exit(
-1);
    }


    
if (object ==0 ){
        cout 
<< "String object is not created" << endl;
        exit(
-1);
    }


    jmethodID mid;
    mid
= Object::env->GetMethodID(clazz,"replaceAll""(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");

    
if (mid==0){
        cerr
<< "GetMethodID Error for class" << endl;
        exit(
-1);
    }


    jvalue array[
2];
    jstring jreg 
= Object::env->NewStringUTF(regex);
    jstring jstr 
= Object::env->NewStringUTF(replacement);

    array[
0].l=jreg;
    array[
1].l=jstr;

    cout 
<< "invoking method" << endl;

    
//傳入參數,調用replaceAll方法
    jobject z=Object::env->CallObjectMethodA(object,mid,array);
    
const char *result=Object::env->GetStringUTFChars((jstring)z, 0);

    
return (const char *)result;
}

3.測試

編寫(xiě)測試代碼

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    
int nRetCode = 0;

    
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)){
        cerr 
<< _T("Fatal Error: MFC initialization failed"<< endl;
        nRetCode 
= 1;
    }
 else{
        
//創(chuàng )建JVM
        Object::BeginJVM();

        String test(
"hello");

        
//調用replaceAll
        const char *result = test.replaceAll("l","z");

        
//返回結果
        cout<< result <<endl;

        
//關(guān)閉JVM
        Object::EndJVM();
    }

    
return nRetCode;
}

4.運行

編譯需要 jni.h和jvm.lib文件。

jni.h在[JAVA_HOME]\include

jvm.lib在[JAVA_HOME]\lib 

運行需要jvm.dll

jvm.dll在[JAVA_HOME]\ jre\bin\client

運行結果如下:

invoking method

invoking method

hezzo

Press any key to continue
發(fā)表于 @ 2008年01月22日 09:06:00 
 
(#)
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
C/C++調用java,以及在cocos2d-x下的實(shí)現
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久