我正在编写一个执行加密,签名等安全模块的程序......我在C中编写了库,它完成了上述功能。现在我使用jni从java调用这个C本机函数。
我遇到的问题是我无法将结果(签名数据或加密数据)存储到java传递的参数中。我想将结果存储在我收到的参数中。请帮我。非常感谢。
以下是我在java中用来调用本机函数的API
sign("sign",byte[] file,int filelen,byte[] output,int outputlen)
在本机C调用中,我将在“文件”上执行登录,该文件是由输入文件内容组成的缓冲区,我想将其存储到输出中。我怎么能这样做,任何人都可以帮助我,我没有找到任何相关信息。
答案 0 :(得分: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;
}
这应该足以让我们了解这个想法。它是从工作代码中解释的,但在当前形式中未经测试。
答案 1 :(得分: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);
}
取决于您的性能注意事项(即,如果您希望确保避免复制数组数据,或避免对字节数组进行并发访问),here is an example使用GetPrimitiveArrayCritical
。
仅当您需要在本机代码和Java代码之间共享缓冲区的时间超过单个函数调用的持续时间时,才建议使用NIO /直接缓冲区。