JNI从DWord返回值

时间:2014-06-05 19:09:06

标签: java c++ java-native-interface

我在头文件

中有一个带有此签名的函数
SIMAPI_DECL DWORD WINAPI SimReadDwordBuffer (DWORD* pBuffer, 
                                             DWORD dwDwordsToRead, 
                                             DWORD* pdwDwordsRead, 
                                             DWORD dwBlockDwords, 
                                             DWORD dwNoWait);

With the following native call defined

protected native int  SimReadDwordBuffer (int[] pBuffer, 
                                          int dwDwordsToRead, 
                                          int pdwDwordsRead, 
                                          int dwBlockDwords, 
                                          int dwNoWait);

我使用javah.exe创建jni标头,它看起来像这样

protected native int  SimReadDwordBuffer (int[] pBuffer, 
                                          int dwDwordsToRead, 
                                          int pdwDwordsRead, 
                                          int dwBlockDwords, 
                                          int dwNoWait);

实施就是这个

JNIEXPORT jint JNICALL Java_com_sig_ccm_CcmBase_SimReadDwordBuffer
  (JNIEnv *env, jobject obj, jintArray pBuffer, jint dwWordsToRead, 
                             jint pdwWordsRead, 
                             jint dwBlockWords, jint dwNoWait){
jint *body = env->GetIntArrayElements(pBuffer, 0);
//DWORD foo = 0;
jint value = SimReadDwordBuffer((unsigned long int *)body,
                         dwWordsToRead,
                                     //&foo, 
                         (unsigned long int *)&pdwWordsRead,
                         dwBlockWords,
                         dwNoWait );
//cout << foo;
env->ReleaseIntArrayElements(pBuffer, body, 0);
return value;
}

问题是无论我尝试过什么,我都无法将pdwWordsRead的值复制到我从java传递给jni的参数。如果我使用局部变量,我可以写出值,所以c ++函数将它传回去。任何建议将不胜感激。

1 个答案:

答案 0 :(得分:0)

Java按值传递基元,而不是通过引用。同样做jint的地址并将它们传递给人口函数也不是一个好主意。

JNIEXPORT jint JNICALL Java_com_sig_ccm_CcmBase_SimReadDwordBuffer
  (JNIEnv *env, jobject obj, jintArray pBuffer, jint dwWordsToRead, 
                             jint pdwWordsRead, 
                             jint dwBlockWords, jint dwNoWait){
jint *body = env->GetIntArrayElements(pBuffer, 0);

// I would consider copying the jint[] to a dword[] here... 
// I would also look into jlong instead of jint because jint 
// is 32-bit signed, and dword is 32-bit unsigned.  Then do 
// something like dword == jlong & 0xFFFFFFFF 

DWORD foo = 0;
jint value = SimReadDwordBuffer((DWORD *) body, // Potentially Bad!
                         (DWORD) dwWordsToRead,
                         &foo, 
                         //(DWORD *) &pdwWordsRead, Bad!
                         dwBlockWords,
                         dwNoWait );
// You need to return an object or something else to get both values out!!! 
env->ReleaseIntArrayElements(pBuffer, body, 0);
return value;
}

同样,我不知道什么是值,但如果它是一个成功指标,检查它并在发生故障时抛出异常并返回foo变量。