[英]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,您可以用Java調用DLL函數。 JNA在內部使用JNI,而不是自己編寫C或C ++,而是編寫Java代碼來描述JNA庫應如何調用DLL函數以及如何轉換參數和返回值。
幫助理解JNA的出色工具:
這似乎是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與字符串一起使用時,可以調用GetStringChars
和NewString
函數來從Win32 API W函數獲取UTF-16LE字符串。 無需轉換; 只要確保跟蹤代碼單位計數和/或字節計數(並為要調用的函數使用正確的計數)即可。 如果您使用的是C ++的STL,則std::wstring
類可能會有所幫助。
如果您的算法需要特定的編碼,則必須找出它的含義。 然后,您可以使用Java String和Charset類在Java字節數組之間進行編碼轉換,或在本機字節數組之間進行Java字節數組轉換,以與DLL函數一起使用。
可能是您的算法無關緊要,但是如果兩個系統正在交換字符串數據,則無論如何都可能需要使用特定的編碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.