<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用

     

    通過(guò)JNI實(shí)現(xiàn)JavaC++的相互調(diào)用

    一、Java調(diào)用C++DLL

    1.    創(chuàng)建Java文件

    創(chuàng)建名為TestNativeJava文件,注意包名。

    package org.druze.test;

    publicclass TestNative {

        publicnativevoid sayHello();

        publicvoid sayHello2(){

           System.out.println("Say Hello From Java");

        }

    }

    如代碼所示,對(duì)于sayHello方法聲明為native,這一部分將由C++的動(dòng)態(tài)庫(kù)來(lái)實(shí)現(xiàn)。

    2.    生成class文件

    使用javac org/druze/test/TestNative.java生成class文件

    注意:執(zhí)行該命令在org所在目錄執(zhí)行。

    3.    使用javah命令生成相應(yīng)的C++頭文件

    使用javah org.druze.test.TestNative生成名為

    org_druze_test_TestNative.h的頭文件

    注意:執(zhí)行該命令在org所在目錄執(zhí)行。

    該頭文件的內(nèi)容如下:

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

    #include <jni.h>

    /* Header for class org_druze_test_TestNative */

    #ifndef _Included_org_druze_test_TestNative

    #define _Included_org_druze_test_TestNative

    #ifdef __cplusplus

    extern "C" {

    #endif

    /*

     * Class:     org_druze_test_TestNative

     * Method:    sayHello

     * Signature: ()V

     */

    JNIEXPORT void JNICALL Java_org_druze_test_TestNative_sayHello

     (JNIEnv *, jobject);

    #ifdef __cplusplus

    }

    #endif

    #endif

    4.    創(chuàng)建C++解決方案

    此處以VS2008為例。

    新建一個(gè)VC++Win32項(xiàng)目,選擇如圖所示的控制臺(tái)應(yīng)用程序。項(xiàng)目名稱為NativeCode

    點(diǎn)擊確定后,再點(diǎn)擊下一步,出現(xiàn)該頁(yè)面,應(yīng)用程序類型選擇DLL,附加選項(xiàng)選擇DLL

    5.    創(chuàng)建號(hào)工程之后,將org_druze_test_TestNative.h導(dǎo)入到工程里面,并創(chuàng)建名為source.cpp的源代碼,內(nèi)容如下:

    #include"org_druze_test_TestNative.h"  

    #include<iostream>  

    using namespace std;  

    JNIEXPORT void JNICALL Java_org_druze_test_TestNative_sayHello(JNIEnv *env, jobject obj)

    {  

        cout<<"Hello World!"<<endl;  

    6.    在工具->選項(xiàng)->項(xiàng)目和解決方案->VC++目錄菜單中,平臺(tái)選擇Win32,選擇“顯示以下內(nèi)容的目錄”為“包含文件”,導(dǎo)入jni.hjni_md.h的路徑。

    7.    編譯,生成NativeCode.dll,并將其copy到環(huán)境變量PATH的路徑下。

    8.    修改TestNative.java

    package org.druze.test;

    publicclass TestNative {

        publicnativevoid sayHello();

        publicstaticvoid main(String[] args) {

            // 加載動(dòng)態(tài)連接庫(kù)DLL,如果沒(méi)有找到的話,則會(huì)在運(yùn)行時(shí)報(bào)錯(cuò)  

            System.loadLibrary("NativeCode");  

              

            TestNative tnt = new TestNative();  

                  

            tnt.sayHello();  

        }

        publicvoid sayHello2(){

           System.out.println("Say Hello From Java");

        }

    }

    運(yùn)行,顯示“Hello World! 

    9.    注意頭文件jni.hjni_md.h可以直接導(dǎo)入到工程中也可以。

    10.注意NativeCode.dll必須放置在java命令能訪問(wèn)的路徑中。

    二、C++調(diào)用Java

    1.創(chuàng)建TestNative2.Java

    package org.druze.test;

    publicclass TestNative2 {

        publicstaticvoid testPrint(){

           System.out.println("this is from static method");

        }

        publicstaticint testReturn(){

           return 22;

        }

        publicstaticint testInput(int number){

           return 22+number;

        }

        publicint testInstance(int number){

           System.out.println("this is from instance method");

           return 11+number;

        }

    }

    2.VS2008中創(chuàng)建win32控制臺(tái)的應(yīng)用程序,命名為NativeCode2,在向?qū)е羞x擇空項(xiàng)目。

    3. 在工具->選項(xiàng)->項(xiàng)目和解決方案->VC++目錄菜單中,平臺(tái)選擇Win32,選擇“顯示以下內(nèi)容的目錄”為“包含文件”,導(dǎo)入jni.hjni_md.h的路徑。直接把jni.hjni_md.h導(dǎo)入到工程中。

    4. 在工具->選項(xiàng)->項(xiàng)目和解決方案->VC++目錄菜單中,平臺(tái)選擇Win32,選擇“顯示以下內(nèi)容的目錄”為“包含文件”,導(dǎo)入jvm.lib的路徑,并在項(xiàng)目->NativeCode2屬性->配置屬性->鏈接器->命令行中添加jvm.lib(這一步或者使用#pragma comment(lib,"jvm.lib")來(lái)代替)。或者將直接將jvm.lib添加到工程中。

    5.創(chuàng)建Test.cpp

    #include <jni.h>

    #include <iostream>

    using namespace std;

    int main()

    {

        JavaVMOption options[1];

        JNIEnv * env;

        JavaVM * jvm;

        JavaVMInitArgs vm_args;

        options[0].optionString = "-Djava.class.path=.";

        vm_args.version = JNI_VERSION_1_6;

        vm_args.nOptions = 1;

        vm_args.options = options;

        vm_args.ignoreUnrecognized = JNI_TRUE;

        long status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

        if (status == JNI_ERR)

        {

            cout<<"Can not create JVM"<<endl;

            return -1;

        }

        printf("Created JVM"n");

        jclass cls = env->FindClass("org/druze/test/TestNative2");

        printf("getCls"n");

         cout<<cls<<endl;

        if (cls !=0)

        {

            jmethodID mid = env->GetStaticMethodID(cls, "testReturn", "()I");

            printf("getMid"n");

            if (mid !=0)

            {

                printf("testReturn"n");

                int result=env->CallStaticIntMethod(cls, mid);

                printf("call over result=%d"n",result);

            }

            mid = env->GetStaticMethodID(cls, "testPrint", "()V");

            if (mid !=0)

            {

                printf("testPrint"n");

                env->CallStaticVoidMethod(cls, mid);

            }

            mid = env->GetStaticMethodID(cls, "testInput", "(I)I");

            if (mid !=0)

            {

                printf("testInput"n");

                int result=env->CallStaticIntMethod(cls, mid,22);

                printf("call over result=%d"n",result);

            }

            mid = env->GetMethodID(cls,"<init>","()V");

            if (mid != 0)//獲取方法成功

            {

                printf("ctro!=0"n");

                jobject obj=env->NewObject(cls, mid);

                printf("new object"n");

                mid = env->GetMethodID(cls, "testInstance","(I)I");

                if (mid!=0)//獲取方法成功

                {

                    printf("methodID!=0"n");

                    jint result=env->CallIntMethod( obj, mid,22);

                    cout<<result<<endl;

                }

            }

        }

        jvm->DestroyJavaVM();

        system("Pause");

        return 0;

    }

    6.jvm.dll目錄添加到PATH環(huán)境變量中,將org/druze/test/TestNative2復(fù)制到debug目錄下執(zhí)行。

    7.頭文件和庫(kù)文件的配置VC6VC2008類似,菜單名稱有所改變。

    VC6中,配置頭文件和庫(kù)文件的目錄在,工具(Tools)->選項(xiàng)(Options)->目錄(Directories)里面的頭文件”Include files”和庫(kù)文件”Library files”.添加相應(yīng)的目錄

    工程(Project)->設(shè)置(Setting)->鏈接(Link)->object/module library后面添加jvm.lib

    CodeBlocksProject->Build options->Linker setting and Search directories中配置相應(yīng)路徑。

    8.按如下結(jié)構(gòu)組織可不用配置jvm.dll到環(huán)境變量中

    創(chuàng)建存放目錄Run(下面的文件目錄在JDK安裝目錄中都能找倒):

    Run(手工建立目錄)

    ----bin(手工建立目錄)

          ----classic(手工建立目錄)

                ----jvm.dll(文件,JDK安裝目錄中有)

                ----自己的JAR包,如果是class文件把包目錄和文件一起拷貝過(guò)來(lái)

                     如果是jar文件,需要在options[1].optionString = "-Djava.class.path=.;./swt.jar";中設(shè)置

                ----JniC.exe,C調(diào)用JAVA的程序

          ----hpi.dll(文件,JDK安裝目錄中有)

          ----ioser12.dll(文件,JDK安裝目錄中有)

          ----java.dll(文件,JDK安裝目錄中有)

          ----net.dll(文件,JDK安裝目錄中有)

          ----verify.dll(文件,JDK安裝目錄中有)

         ----zip.dll(文件,JDK安裝目錄中有)

    ----lib(手工建立目錄)

          ----zi(目錄,JDK安裝目錄中有,全部拷貝過(guò)來(lái))

          ----rt.jar(文件,JDK安裝目錄中有)

          ----tzmappings(文件,JDK安裝目錄中有)

    三、JNI代碼分析(待續(xù))

    posted on 2008-07-29 12:48 role0523-- 閱讀(11425) 評(píng)論(23)  編輯  收藏

    評(píng)論

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用 2008-07-29 14:14 Always BaNg.

    不錯(cuò),把字符轉(zhuǎn)換也一并講了吧,比如UTF-8的處理,USC-2與MBCS轉(zhuǎn)換等。  回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用[未登錄](méi) 2008-07-29 14:17 role0523

    你是指Java和C++之間的字符轉(zhuǎn)換?
    目前還沒(méi)有研究過(guò)字符轉(zhuǎn)換。
      回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用 2008-07-31 23:58 coldsummer

    如果是現(xiàn)成的dll呢?比如某硬件提供的開(kāi)發(fā)dll開(kāi)發(fā)包,我如何調(diào)用?  回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用[未登錄](méi) 2008-08-01 00:05 role0523

    @coldsummer
    由于JAVA調(diào)用C++需要一定的格式,比如在JAVA中聲明native方法,然后通過(guò)javah生成一個(gè)頭文件,然后寫(xiě)cpp文件,但必須實(shí)現(xiàn)這個(gè)頭文件中聲明的JNIEXPORT方法。這些方法是Java調(diào)用C++的入口。所以在這些方法內(nèi)部填寫(xiě)對(duì)你的DLL的調(diào)用即可。  回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用 2008-08-26 17:14 lfking

    你的這個(gè)JAVA調(diào)用C++的例子,我試了一整天,沒(méi)試明白!~~
    在最后編譯成DLL文件時(shí)老是報(bào)錯(cuò),不知道是怎么回事!~~~
    錯(cuò)誤代碼如下:請(qǐng)你幫分析一下!謝謝!~

    c:\documents and settings\william\my documents\visual studio 2005\projects\nativecode\nativecode\source.cpp(5) : error C2144: syntax error : 'void' should be preceded by ';'
    c:\documents and settings\william\my documents\visual studio 2005\projects\nativecode\nativecode\source.cpp(5) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    c:\documents and settings\william\my documents\visual studio 2005\projects\nativecode\nativecode\source.cpp(5) : error C2146: syntax error : missing ';' before identifier 'Java_org_druze_test_TestNative_sayHello'
    c:\documents and settings\william\my documents\visual studio 2005\projects\nativecode\nativecode\source.cpp(5) : error C2182: 'JNICALL' : illegal use of type 'void'
    c:\documents and settings\william\my documents\visual studio 2005\projects\nativecode\nativecode\source.cpp(5) : error C2065: 'JNIEnv' : undeclared identifier
    c:\documents and settings\william\my documents\visual studio 2005\projects\nativecode\nativecode\source.cpp(5) : error C2065: 'env' : undeclared identifier
    c:\documents and settings\william\my documents\visual studio 2005\projects\nativecode\nativecode\source.cpp(5) : error C2065: 'jobject' : undeclared identifier
    c:\documents and settings\william\my documents\visual studio 2005\projects\nativecode\nativecode\source.cpp(5) : error C2146: syntax error : missing ')' before identifier 'obj'
    c:\documents and settings\william\my documents\visual studio 2005\projects\nativecode\nativecode\source.cpp(5) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    c:\documents and settings\william\my documents\visual studio 2005\projects\nativecode\nativecode\source.cpp(5) : error C2078: too many initializers
    c:\documents and settings\william\my documents\visual studio 2005\projects\nativecode\nativecode\source.cpp(5) : error C2059: syntax error : ')'
    c:\documents and settings\william\my documents\visual studio 2005\projects\nativecode\nativecode\source.cpp(6) : error C2143: syntax error : missing ';' before '{'
    c:\documents and settings\william\my documents\visual studio 2005\projects\nativecode\nativecode\source.cpp(6) : error C2447: '{' : missing function header (old-style formal list?)
    Generating Code...
    生成日志保存在“file://c:\Documents and Settings\william\My Documents\Visual Studio 2005\Projects\NativeCode\NativeCode\Debug\BuildLog.htm”
    NativeCode - 13 個(gè)錯(cuò)誤,0 個(gè)警告
    ========== 全部重新生成: 0 已成功, 1 已失敗, 0 已跳過(guò) ==========
      回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用[未登錄](méi) 2008-08-26 17:38 role0523

    你沒(méi)有指定jni.h,jni_md.h的include path,以及 jvm.dll的路徑,具體參考文章后半部分  回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用 2008-08-27 10:24 lfking

    你說(shuō)要指定jni.h 和 jni_md.h的include path 這個(gè)我都做了,就是少做一個(gè)JVM.DLL的路徑,試過(guò)了,還是一樣的錯(cuò)誤!~
    我做的是JAVA 連接 C++ 需要做這個(gè)JVM.DLL的路徑嗎?  回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用[未登錄](méi) 2008-08-27 10:46 role0523

    sorry, jvm.dll不用指定,因?yàn)槲覀冞@里不需要它。

    這樣好了,你把org_druze_test_TestNative.h和jni.h復(fù)制到source.cpp相同的目錄下,將#include <jni.h>修改為#include "jni.h" 試試看。

    你的問(wèn)題是jni.h的頭文件沒(méi)有在頭文件的搜索路徑當(dāng)中。  回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用 2008-08-27 12:01 lfking

    我按照你上面寫(xiě)的步聚建立一個(gè)WIN32的工程,建好以后,會(huì)自動(dòng)建立一個(gè)stdafx.h的頭文件和stdafx.cpp文件!然后運(yùn)行source.cpp的時(shí)候提示錯(cuò)誤說(shuō)必須要用stdafx.h這個(gè)頭文件,加上去以后就出現(xiàn)這些錯(cuò)誤了!

    唉!~把jni.h放到source.cpp同一個(gè)目錄下了,還是不行!~~
    我留個(gè)QQ號(hào)給你吧,Q上聊!47145748!
    你這BOLG上面不能發(fā)圖片!
      回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用 2008-08-27 12:04 lfking

    vc以前從來(lái)沒(méi)接觸過(guò),只是聽(tīng)說(shuō)過(guò)!所以用起來(lái)有點(diǎn)愚純!~~抱歉!~~  回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用[未登錄](méi) 2008-08-27 15:12 role0523

    你把stdafx.h的頭文件和stdafx.cpp刪除掉吧  回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用 2008-08-28 10:31 lfking

    無(wú)語(yǔ)了都.....
    如果把stdafx.h和stdafx.cpp刪除的話,會(huì)提示錯(cuò)誤,說(shuō)沒(méi)有加載stdafx.h文件。
    大哥,這個(gè)例子你試過(guò)沒(méi)啊??是否成功了?你那個(gè)版本的VC??我是用VC2005做的!  回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用[未登錄](méi) 2008-08-28 11:00 role0523

    就如我文中所說(shuō),我用的VS2008,VC6,codeBlocks.我沒(méi)搞定,不會(huì)寫(xiě)東西的。你的問(wèn)題在于你對(duì)C++的編譯器不是很熟悉,這我?guī)筒涣四恪?

    BTW:如果把stdafx.h和stdafx.cpp刪除的話,會(huì)提示錯(cuò)誤,說(shuō)沒(méi)有加載stdafx.h文件。

    那是你的某個(gè)地方#include了這個(gè)文件,OK?  回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用 2008-08-28 14:53 lfking

    7.編譯,生成NativeCode.dll,并將其copy到環(huán)境變量PATH的路徑下。
    10.注意NativeCode.dll必須放置在java命令能訪問(wèn)的路徑中。

    這個(gè)不是很了解。能不能在說(shuō)的具體點(diǎn)!
    我是把NativeCode.dll放在與TestNative.java文件同一個(gè)目錄下!   回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用[未登錄](méi) 2008-08-28 14:58 role0523

    NativeCode.dll是由java.exe->jvm.dll->NativeCode.dll這樣調(diào)用的。你把NativeCode.dll放到與java.exe同目錄下,OK?
      回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用 2009-05-21 18:10 Necho

    完全按照樓主的做法結(jié)果確報(bào)這個(gè)錯(cuò)誤,請(qǐng)樓主幫我看下吧

    First-chance exception at 0x00411a20 in NativeCode2.exe: 0xC0000005: Access violation reading location 0x00000000.
    Unhandled exception at 0x00411a20 in NativeCode2.exe: 0xC0000005: Access violation reading location 0x00000000.  回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用 2009-05-21 18:21 Necho

    補(bǔ)充一下 應(yīng)該就是不能findclass  回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用 2009-05-21 18:24 Necho

    如果可以的話 請(qǐng)加我MSN:necho_leco@yhotmail.com
    或者QQ :55128128
    想向你請(qǐng)教,謝謝~!   回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用 2009-05-22 10:19 Necho

    測(cè)試成功了 感謝LZ提供這么詳細(xì)的說(shuō)明 謝謝~~!!  回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用[未登錄](méi) 2009-09-04 14:43 阿飛

    樓主,請(qǐng)問(wèn)下:我在VC6。0控制臺(tái)下可以加載JAVA虛擬機(jī)了,為什么到了VC6.0的MFC下用同樣的方法加載不了(編譯不報(bào)錯(cuò),但是調(diào)試的時(shí)候通不過(guò)),盼回復(fù),謝謝!  回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用[未登錄](méi) 2009-12-18 13:40 sunny

    樓主:
    請(qǐng)問(wèn)我在編譯C++時(shí),出現(xiàn)這個(gè)錯(cuò)誤訊息:
    error C2065: 'JNI_VERSION_1_6' : undeclared identifier

    我使用的是JDK1.6  回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用 2009-12-18 23:39 nobody

    @sunny 看看這個(gè)聲明在哪個(gè)頭文件里面,把它include進(jìn)來(lái)
      回復(fù)  更多評(píng)論   

    # re: 通過(guò)JNI實(shí)現(xiàn)Java和C++的相互調(diào)用 2010-01-09 11:52 next

    @lfking
    朋友,這個(gè)連接的最下方是你要的答案
    http://www.experts-exchange.com/Programming/Languages/CPP/Q_22048796.html

    引用:
    phongtran72:
    Well, this generates error:

    #include "jni.h"
    #include "stdafx.h"
    #include <stdlib.h>
    #include <stdio.h>

    And this is solution:

    #include "stdafx.h"
    #include <stdlib.h>
    #include <stdio.h>
    #include "jni.h"  回復(fù)  更多評(píng)論   


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     

    導(dǎo)航

    <2008年8月>
    272829303112
    3456789
    10111213141516
    17181920212223
    24252627282930
    31123456

    統(tǒng)計(jì)

    常用鏈接

    留言簿(3)

    隨筆檔案

    搜索

    最新評(píng)論

    主站蜘蛛池模板: 免费人成网站在线播放| 中文字幕专区在线亚洲| 国产偷国产偷亚洲高清日韩| 亚洲五月六月丁香激情| 亚洲精品久久久久无码AV片软件| 色费女人18女人毛片免费视频| 久久久久久久岛国免费播放| 国产网站免费观看| 午夜亚洲AV日韩AV无码大全| 久久久久久亚洲av无码蜜芽| 无码AV片在线观看免费| 四虎影视精品永久免费| 亚洲狠狠狠一区二区三区| 免费人成大片在线观看播放电影| 18禁黄网站禁片免费观看不卡| 亚洲男人在线无码视频| 亚洲伊人久久大香线蕉结合| 99久久免费国产精精品| 日本免费一二区在线电影| 久久国产亚洲精品无码| 免费人人潮人人爽一区二区| 亚洲天堂免费在线| 久久精品亚洲视频| 成人a毛片视频免费看| 国产免费AV片在线播放唯爱网| 亚洲精品乱码久久久久久中文字幕| 亚洲日韩看片无码电影| 在线成人爽a毛片免费软件| 久久久久亚洲精品天堂久久久久久| 亚洲中文字幕无码爆乳| 中文字幕免费在线观看| 亚洲日韩精品无码一区二区三区 | 污网站免费在线观看| 一色屋成人免费精品网站| 亚洲av永久无码精品网站 | 国产AV无码专区亚洲AV琪琪| 一本无码人妻在中文字幕免费| 亚洲福利视频导航| 99久久99这里只有免费的精品| 亚洲国产综合久久天堂| 亚洲国产av玩弄放荡人妇|