2012-07-14 20 views
1

我正在編寫一個程序,用於執行諸如加密,簽名等安全模塊......我已經在C中編寫了具有上述功能的庫。現在我使用jni從java中調用這個C原生函數。如何在Java參數中存儲傳遞給JNI本地C調用的值

我面對的問題是我無法將結果(簽名數據或加密數據)存儲到java傳遞的參數中。我想將結果存儲在我收到的參數中。請幫幫我。非常感謝提前。

以下是我在Java用來調用本地函數

sign("sign",byte[] file,int filelen,byte[] output,int outputlen) 

在本地C調用API我將在「文件」,這是一個緩衝器執行的符號由輸入文件的內容,我想將其存儲到輸出中。我怎麼能做到任何人都可以幫助我我沒有找到任何相關信息。

+0

Java按值傳遞參數,所以您將無法爲參數分配值。不過,您可以填寫給定的字節數組。而Java數組有一個'length'屬性,所以將這個長度作爲附加參數傳遞是沒有用的。 – 2012-07-14 09:46:27

回答

0

以下代碼允許您的本機代碼直接訪問基本字節數組輸入的內容。

JNIEXPORT void JNICALL Java_*mypackage*_sign(JNIEnv* env, jbytearray input, jint ilen, jbytearray output, jint olen) { 
    char* pinput = (*env)->GetByteArrayElements(env, input, NULL); 
    char* poutput = (*env)->GetByteArrayElements(env, output, NULL); 

    sign(pinput, ilen, poutput, olen); 

    (*env)->ReleaseByteArrayElements(env, input, pinput, 0); 
    (*env)->ReleaseByteArrayElements(env, output, poutput, 0); 
} 

根據你的表現考慮(即如果你想確保你避免複製數組數據,或避免到字節數組併發訪問),使用GetPrimitiveArrayCriticalhere is an example

只有當您需要在本地代碼和Java代碼之間共享緩衝區的時間超過單個函數調用的持續時間時,才建議使用NIO /直接緩衝區。

+0

謝謝你的迴應。我能夠訪問到本地代碼的輸入內容,我對收到的輸入執行了一些操作,它工作正常。現在我的擔心是將數據存儲回輸出參數,我試圖通過將值分配給收到的參數,即輸出到上下文中,但它不起作用。我該怎麼做,請幫我... – thiru 2012-07-17 09:47:20

+0

上面的例子確保寫入「輸出」參數緩衝區的任何內容都顯示在輸出基本數組中。如果你想返回寫入輸出數組的字節數,你可以簡單地使用它作爲返回值(而不是「void」)。 – technomage 2012-07-17 11:35:16

1

通常,使用直接的ByteBuffer調用本地庫。

接口MyClass.submit(ByteBuffer source, ByteBuffer dest)

static jmethodID ByteBuffer_position; 
static jmethodID ByteBuffer_limit; 

// Find method id's for ByteBuffer methods. 
JNIEXPORT jint JNICALL Java_MyClass_initAPI 
    (JNIEnv *env, jclass thisj) { 
    jint error = 0; 

    ByteBuffer_position = (*env)->GetMethodID(env, byteBufferClass, "position", "()I"); 
    if (ByteBuffer_position == NULL) error = -1; 
    ByteBuffer_limit = (*env)->GetMethodID(env, byteBufferClass, "limit", "()I"); 
    if (ByteBuffer_limit == NULL) error = -1; 

    return error; 
} 

// Get ByteBuffer pointers and sizes and encrypt 
// Expects source buffer's position to indicate end of source 
// Expects dest buffer's limit to indicate max output length 
JNIEXPORT jint JNICALL Java_MyClass_submit (JNIEnv *env, jobject thisj, 
    jobject sourceBuffer, jobject destBuffer) { 
    jint error = 0; 

    unsigned char* sourcePtr = (*env)->GetDirectBufferAddress(env, source); 
    unsigned char* destPtr = (*env)->GetDirectBufferAddress(env, dest); 
    jlong sourceLen = (*env)->CallIntMethod(env, source, ByteBuffer_position); 
    jlong destLen = (*env)->CallIntMethod(env, dest, ByteBuffer_limit); 

    // Encrypt sourcePtr --> destPtr 

    return error; 
} 

這應該足以傳達出的主意。它是從工作代碼中解釋出來的,但是沒有經過當前的測試。

相關問題