簡體   English   中英

使用jni在Java中實現vc ++方法

[英]implementing a vc++ method in java using jni

我是使用Java本機接口的新手。 我的任務是在中實現vc ++方法

Java的 我需要在Java中實現的方法使用vc ++中的dll方法

方法。 我的問題是,是否足以在Java中聲明本機方法並調用

本機聲明的方法還是我仍然需要使用以下方法將代碼從C ++重寫為Java

jni。 有人可以建議我如何做嗎,我看了文章但並不完全

了解jni在做什么。 這是我必須在Java中實現的方法

內部調用的方法來自m_hSecdll,所以我應該如何在

java實現此getauthorization方法

bool HtmlWindow::GetAuthorizationHeader(CString &sName, CString &sValue)
        {          
                //type enum
            SecStatus stat;
                //typedef for long typw
            SecContextHandle hCurrentCtx;
            //typedef for struct
                SecBufferHandle hBuf = NULL; 

            try
            {
                if (!m_hSecdll)
                {
                    m_hSecRtl = AfxLoadLibrary(_T("secdll"));
                }

                if (!m_hSecdll)
                {
                    AfxMessageBox(IDS_ERR_SECDLL);
                    return false;
                }

                //get the function to call SecGetContext
                typedef SecStatus (_stdcall *FN2)(SecContextHandle*);
                FN2 pFN2 = (FN2) ::GetProcAddress(m_hSecRtl, _T("SecGetContext"));
                if (!pFN2)
                {
                    AfxMessageBox(IDS_ERR_SECRTL_SECGETCONTEXT);
                    return false;
                }

                //call it
                stat = (*pFN2)(&hCurrentCtx);
                if (stat != eSecOk) {
                    AfxMessageBox(IDS_ERR_MPAGES_SERVICE_CONTEXT);
                    return false;
                }

                //get the function to call SecExportContext
                typedef SecStatus (_stdcall *FN3)(SecBufferHandle*, const SecContextHandle, const char*, const uint);
                FN3 pFN3 = (FN3) ::GetProcAddress(m_hSecRtl, _T("SecExportContext"));
                if (!pFN3)
                {
                    AfxMessageBox(IDS_ERR_SECRTL_SECEXPORTCONTEXT);
                    return false;
                }

                //call it
                stat = (*pFN3)(&hBuf, hCurrentCtx, NULL, 0);
                if (stat != eSecOk) {
                    AfxMessageBox(IDS_ERR_MPAGES_SERVICE_EXPORT);
                    return false;
                }

                //get the function to call SecExportContext
                typedef void* (_stdcall *FN4)(SecBufferHandle);
                FN4 pFN4 = (FN4) ::GetProcAddress(m_hSecRtl, _T("SecGetBufferPtr"));
                if (!pFN4)
                {
                    AfxMessageBox(IDS_ERR_SECRTL_SECGETBUFFERPTR);
                    return false;
                }

                //call it
                unsigned char * c = (unsigned char*)(*pFN4)(hBuf);

                //get the function to call SecExportContext
                typedef long (_stdcall *FN5)(SecBufferHandle);
                FN5 pFN5 = (FN5) ::GetProcAddress(m_hSecRtl, _T("SecGetBufferLen"));
                if (!pFN5)
                {
                    AfxMessageBox(IDS_ERR_SECRTL_SECGETBUFFERLEN);
                    return false;
                }

                //call it
                int length = (*pFN5)(hBuf);

                int x = 0;
                char * hex = new char[length*2];
                for (int i = 0; i < length; i++)
                {
                    CString sTemp;
                    sTemp.Format("%x",c[i]);
                    if (sTemp.GetLength()==1)
                        sTemp = _TCHAR('0') + sTemp;

                    hex[x++] = sTemp[0];
                    hex[x++] = sTemp[1];
                }

                sName = "Some String";
                sValue = CString(hex,length*2); 
                delete [] hex;

            }
            catch (...)
            {
                AfxMessageBox(IDS_ERR_SECDLL_UNKNOWN);
                return false;
            }

            return true;
    }

傑尼

使用JNI,您可以用C或C ++實現Java方法(類靜態成員或對象實例成員)。 C或C ++代碼使用JNI函數將參數從Java傳遞到本機,調用本機函數,然后使用JNI函數將返回值從本機傳遞到Java。 當然,在兩個類型系統中具有相同表示形式的簡單類型不需要任何轉換。 您還可以使用JNI函數創建Java對象,調用方法,訪問字段以及引發和處理異常。

重要參考:

JNA

使用JNA,您可以用Java調用DLL函數。 JNA在內部使用JNI,而不是自己編寫C或C ++,而是編寫Java代碼來描述JNA庫應如何調用DLL函數以及如何轉換參數和返回值。

幫助理解JNA的出色工具:

  • JNAerator (與所需的DLL函數和結構的簡化C頭一起使用)

GetAuthorizationHeader

這似乎是C ++類的成員。 如果它不是靜態的,並且您需要在Java本機方法調用之間保留對其實例的引用,那么您的問題就大得多。 如果它是靜態的(或者可以這樣做),那么如果您走JNI路由,則可以直接使用它。 但是,GetAuthorizationHeader的實際功能似乎非常簡單,因此可以內聯或在Java中使用JNA路由重新實現。

弦樂

每個字符串都有一個字符集和編碼(即代碼頁)。 Java使用Unicode UTF-16LE或UTF-16BE(取決於平台)。 Windows使用UTF-16LE。 您的代碼是使用ambidextrous _T()宏編寫的,並調用ambidextrous Win32 API函數。 Win32具有FunctionA函數和FunctionW函數。 W是Unicode。 您很可能會放棄對不支持Unicode的Windows版本的支持。 如果您在現代Windows上調用A函數,則必須將其轉換為Unicode並再次返回,因此無論如何您還是可以調用W函數。

在Visual C ++中,字符串文字表示為Unicode的L“ string”,類型為wchar_t且為UTF-16LE。 在C ++中, wchar_t是平台相關的字符類型。 您的C ++版本可能不支持新的C ++ char16_t因此您可以替換wchar_t

當將JNI與字符串一起使用時,可以調用GetStringCharsNewString函數來從Win32 API W函數獲取UTF-16LE字符串。 無需轉換; 只要確保跟蹤代碼單位計數和/或字節計數(並為要調用的函數使用正確的計數)即可。 如果您使用的是C ++的STL,則std::wstring類可能會有所幫助。

如果您的算法需要特定的編碼,則必須找出它的含義。 然后,您可以使用Java String和Charset類在Java字節數組之間進行編碼轉換,或在本機字節數組之間進行Java字節數組轉換,以與DLL函數一起使用。

可能是您的算法無關緊要,但是如果兩個系統正在交換字符串數據,則無論如何都可能需要使用特定的編碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM