好的,我之前已经问过这个问题,但我认为答案在这方面有所不同。所以基本上我有一个C库,其中包含函数seal和unseal,如下所示:
JNIEXPORT jint JNICALL Java_JavaTest_securesdk_1seal_1data
(JNIEnv *env, jobject obj, jlong handle, jbyteArray data, jint size)
{
const char *cData = (*env)->GetByteArrayElements(env, data NULL);
jint token = securesdk_seal_data(handle, cData, size);
(*env)->ReleaseByteArrayElements(env, data, cData, JNI_ABORT);
return token;
}
JNIEXPORT jint JNICALL Java_JavaTest_securesdk_1unseal_1data
(JNIEnv *env, jobject obj, jlong handle, jint token, jbyteArray data, jint size)
{
const char *buffer = (*env)->GetByteArrayElements(env, data NULL);
jsize length = (*env)->GetArrayLength(env,data);
jlong address = securesdk_unseal_data(handle, token, buffer, size);
for(int i=0; i<length; i++){
printf("%i\n", buffer[i])
}
(*env)->ReleaseByteArrayElements(env, data, buffer, JNI_ABORT);
return address;
}
基本上,seal函数接受Java端的字节数组并将其存储在闪存中(不用担心它是如何工作的)并返回一个令牌。 unseal函数接受一个空字节数组缓冲区和令牌,并用数据填充空缓冲区。现在这里是java代码及其输出内容。
class JavaTest{
public native int securesdk_seal_data(long handle, byte[] data, int size);
public native int securesdk_unseal_data(long handle, int token, byte[] data, int size);
JavaTest test = new JavaTest();
String data = "hello";
byte[] cmdbuf = data.getBytes();
int token = test.securesdk_seal_data(sdk, cmdbuf, cmdbuf.length);
byte[] emptybuf = new byte[10];
long returnData = test.securesdk_unseal_data(sdk, token, emptybuf, emptybuf.lenth);
for(int i=0; i<emptybuf.length; i++){
System.out.print(emptybuf[i]);
}
}
因此,当我运行java代码时,它会从C代码中的printf语句中打印出“hello”的字节。当我传入空缓冲区时,它会填充我最初密封的数据。这是正确的。但是当我在Java中调用unseal函数后尝试打印填充的缓冲区时,它仍然返回空缓冲区。如何在调用C函数后从内存中获取缓冲区?这可能吗?当我从Java打印emptybuf时,我希望打印出“hello”的字节,而不仅仅是来自C.谢谢。
答案 0 :(得分:0)
在开封中,而不是JNI_ABORT传递0:
(*env)->ReleaseByteArrayElements(env, data, buffer, 0);