Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JNIJava包装器:如何传递byte[]参数 我需要用JNI调用C++的java API。我正在尝试传递一个字节*,如下所示:_Java_C++_Java Native Interface - Fatal编程技术网

JNIJava包装器:如何传递byte[]参数 我需要用JNI调用C++的java API。我正在尝试传递一个字节*,如下所示:

JNIJava包装器:如何传递byte[]参数 我需要用JNI调用C++的java API。我正在尝试传递一个字节*,如下所示:,java,c++,java-native-interface,Java,C++,Java Native Interface,Java void OperateData(字节[]数据,int数据长度) { //一些实现 } C++ void OperateData(字节*数据,int数据长度) { JavaMethod*methodObj=getMethod(_T(“OperateData”); JNIEnv*JNIEnv=JvmManager::GetInstance()->GetJNIEnv(); jobject jBuffer=jniEnv->CallObjectMethod(m_javaObject->get

Java

void OperateData(字节[]数据,int数据长度)
{
//一些实现
}
C++

void OperateData(字节*数据,int数据长度)
{
JavaMethod*methodObj=getMethod(_T(“OperateData”);
JNIEnv*JNIEnv=JvmManager::GetInstance()->GetJNIEnv();
jobject jBuffer=jniEnv->CallObjectMethod(m_javaObject->getJObject(),methodObj->getJMethodID(),(jobject)数据,(jint)数据长度);
}
这是行不通的。它抛出了一个异常。你能告诉我我做错了什么吗

<强>更新< /强>:我根据建议修改C++代码如下。我还是有同样的问题。还有什么不对劲吗

void OperateData(字节*数据,int数据长度)
{
JavaMethod*methodObj=getMethod(_T(“OperateData”);
JNIEnv*JNIEnv=JvmManager::GetInstance()->GetJNIEnv();
jbyteArray jBuff=jniEnv->NewByteArray(数据长度);
jniEnv->SetByteArrayRegion(jBuff,0,dataLength,(jbyte*)数据);
jobject jBuffer=jniEnv->CallObjectMethod(m_javaObject->getJObject(),methodObj->getJMethodID(),jBuff,(jint)数据长度);
jniEnv->ReleaseByteArrayElements(jBuff,(jbyte*)数据,0);
}
所有这些都毫无意义

  • JNI方法签名包含参数和返回类型信息,如
    javap-s
    的输出所示。因此Java方法的JNI签名肯定不仅仅是
    “OperateData”
  • 因此,您的
    methodObj
    必须为null,或者包含一个为零的
    jmethodID
    ,仅此一点就足以解释您的问题
  • 这段代码中惊人地缺少错误检查。必须对每个JNI调用的结果进行错误检查
  • 您调用的Java方法是
    void
    ,因此它不会返回
    jobject
  • 您正在调用的Java方法是
    void
    ,因此您应该使用
  • 需要使用C++代码> CAR**DATABAS/<代码>转换为<代码> JByTurray,使用<代码> NeWyTeLayLaye()/Cult>,并使用适当的.< /LI>填充它。
  • 您调用的
    ReleaseByteArrayElements()
    不正确。在这里您根本不需要调用它,但是当您调用它时,它会被通过
    getbytearrayellements()
    获得的指针调用。不是用你自己的数据
  • 打完电话后,如果你已经完成了,你应该这样做

  • 您不能简单地将原始C/C++
    byte*
    指针类型转换为表示Java字节数组的
    jobject
    。您需要:

    • 通过在JVM内存中分配一个新的Java字节数组

    • 然后通过以下任一方式将原始字节复制到该Java数组的内存中:

      • memcpy()
        ,以及

    • 然后将该Java数组传递给目标Java方法

    • 最后通过发布Java数组

    例如:

    void OperateData(byte* data, int dataLength)
    {
        JavaMethod* methodObj = getMethod(_T("OperateData"));
        if (!methodObj) return;
        JNIEnv* jniEnv = JvmManager::GetInstance()->GetJNIEnv();
        if (!jniEnv) return;
        jbyteArray jData = jniEnv->NewByteArray((jsize)dataLength);
        if (!jData) return;
        jniEnv->SetByteArrayRegion(jData, 0, (jsize)dataLength, (jbyte*)data);
        jniEnv->CallVoidMethod(m_javaObject->getJObject(), methodObj->getJMethodID(), jData, (jint)dataLength);
        jniEnv->DeleteLocalRef(jData);
    }
    
    更新:在评论中,您说您将Java代码更改为返回一个
    字节[]
    ,而不是
    无效
    。如果是这样,你需要相应地调整C++代码,例如:

    void OperateData(byte* data, int dataLength)
    {
        JavaMethod* methodObj = getMethod(_T("OperateData"));
        if (!methodObj) return;
        JNIEnv* jniEnv = JvmManager::GetInstance()->GetJNIEnv();
        if (!jniEnv) return;
        jbyteArray jData = jniEnv->NewByteArray((jsize)dataLength);
        if (!jData) return;
        jniEnv->SetByteArrayRegion(jData, 0, (jsize)dataLength, (jbyte*)data);
        jobject jBuffer = jniEnv->CallObjectMethod(m_javaObject->getJObject(), methodObj->getJMethodID(), jData, (jint)dataLength);
        if (jBuffer) jniEnv->DeleteLocalRef(jBuffer);
        jniEnv->DeleteLocalRef(jData);
    }
    

    如果您看到一个异常,您将希望发布完整的stacktrace和您的问题,它将提交为catch处理的未知异常(…)根据您的建议修改JNI,如下所示:void OperateData(byte*data,int dataLength){JavaMethod*methodObj=getMethod(_T(“OperateData”))JNIEnv*JNIEnv=JvmManager::GetInstance()->GetJNIEnv();jbyteArray jBuff=JNIEnv->NewByteArray(dataLength);JNIEnv->SetByteArrayRegion(jBuff,0,dataLength,(jbyte*)数据);jobject jBuffer=JNIEnv->CallObjectMethod(m_javaObject->->getJObject(),methodObj->getjmethododid(),jBuff,(jint)dataLength);}@LokanathNayak关闭。您没有进行错误处理,并且在完成时没有释放Java数组
    JObject
    应该是
    JObject
    。请参见编辑历史记录。这是我唯一编辑的东西,现在不在那里了。@EJP您在我自己编辑的时候做了编辑。你的编辑丢失了。我重新应用了它没问题,我知道它是怎么发生的。
    void OperateData(byte* data, int dataLength)
    {
        JavaMethod* methodObj = getMethod(_T("OperateData"));
        if (!methodObj) return;
        JNIEnv* jniEnv = JvmManager::GetInstance()->GetJNIEnv();
        if (!jniEnv) return;
        jbyteArray jData = jniEnv->NewByteArray((jsize)dataLength);
        if (!jData) return;
        jniEnv->SetByteArrayRegion(jData, 0, (jsize)dataLength, (jbyte*)data);
        jobject jBuffer = jniEnv->CallObjectMethod(m_javaObject->getJObject(), methodObj->getJMethodID(), jData, (jint)dataLength);
        if (jBuffer) jniEnv->DeleteLocalRef(jBuffer);
        jniEnv->DeleteLocalRef(jData);
    }