我在我的C庫中有一個unsigned char*
,我調用一個JNI導出的函數,需要用這個數據設置一個java對象,最好在byte[]
。JNI/C庫:傳遞字節ptr
但是這個函數會被經常調用,而且它需要複製大量的數據。
是否可以使用ByteBuffer並將該ByteBuffer的指針指定給我的unsigned char*
?或者它只是反過來工作?
可我甚至做這沒有拷貝數據?訪問它的最佳方式是什麼?
unsigned char*
中的數據大小是已知的。
我在我的C庫中有一個unsigned char*
,我調用一個JNI導出的函數,需要用這個數據設置一個java對象,最好在byte[]
。JNI/C庫:傳遞字節ptr
但是這個函數會被經常調用,而且它需要複製大量的數據。
是否可以使用ByteBuffer並將該ByteBuffer的指針指定給我的unsigned char*
?或者它只是反過來工作?
可我甚至做這沒有拷貝數據?訪問它的最佳方式是什麼?
unsigned char*
中的數據大小是已知的。
考慮到您提供的信息很少,這裏有一個可能的解決方案。
對事物的Java端,你會:
package com.stackoverflow;
public class JNIQuestion
{
static native void fillByteArray(byte[] buffer);
}
而在C面你會:
JNIEXPORT void JNICALL Java_com_stackoverflow_JNIQuestion_fillByteArray(JNIEnv* env, jbyteArray array)
{
jboolean isCopy;
jbyte* buffer = (*env)->GetByteArrayElements(env, array, &isCopy);
jsize length = (*env)->GetArrayLength(env, array);
jsize i;
// do something with the buffer here, replace with something meaningful
// PAY ATTENTION TO BUFFER OVERFLOW, DO NOT WRITE BEYOND BUFFER LENGTH
for (i = 0; i < length; ++i)
buffer[i] = i;
// here it is important to use 0 so that JNI takes care of copying
// the data back to the Java side in case GetByteArrayElements returned a copy
(*env)->ReleaseByteArrayElements(env, buffer, 0);
}
使用直接ByteBuffer
(ByteBuffer.allocateDirect()
)也是一個可能的解決方案。但是我只用一個直接ByteBuffer
當我需要在緩衝區中的Java端填寫的數據非常精確的偏移。
關於性能,使用byte[]
的解決方案應該是令人滿意的,因爲在調用GetByteArrayElements()
時,JVM可能會固定字節數組而不是複製它。
一般來說,您會希望儘量減少JNI調用的數量,這意味着從C端訪問對象字段或從C端分配Java將會影響性能。
在任何情況下,輪廓第一,優化下。
PS:我沒有嘗試編譯代碼,可能有錯別字。請參閱JNI Guide和JNI Tutorial。
請給出您的本地方法在Java簽名,以便有人可以找出一個明智的解決方案 – 2009-12-04 18:45:08
@Gregory:它只需要一個對象作爲參數...訪問字段不是問題,分配一個指針或將數據複製到字節[]字段中。 – John 2009-12-04 18:56:14
是什麼問題?這是一個性能問題還是你沒有成功填充數據? – 2009-12-04 19:04:02