2012-07-14 21 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; 
} 

这应该足以传达出的主意。它是从工作代码中解释出来的,但是没有经过当前的测试。

相关问题