未在此范围内声明 GetByteArrayElements

GetByteArrayElements was not declared in this scope

我正在尝试使用 C++ 在 Java 中创建本机方法。但是,我的 g++ 编译器一直告诉我我的 GetByteArrayElements 函数没有声明。我把jni.h和对应的头文件都包含到我的class里了,不知道哪里不对。请帮助我。

我已经尝试更改参数以查看是否是问题所在。不是,把env放在前面也没有用。

#include<algorithm>
#include<string>
#include<vector>
#include<jni.h>
#include"com_package_name_ClassName.h"
#define apnd push_back
#define nperm std::next_permutation
typedef std::vector<std::string> slist;
JNIEXPORT jbyteArray JNICALL Java_com_package_name_ClassName_permute(JNIEnv*env,jclass cls,jbyteArray ba)
{
    bool cp=false;
    jbyte*bt=GetByteArrayElements(*ba,&cp);
    std::string str=std::string((char*)bt,env->GetArrayLength(ba));
    std::string*ps=new std::string(),tmp=str;
    slist*perms=new slist();
    perms->apnd(str);
    nperm(tmp.begin(),tmp.end());
    while(tmp!=str)
    {
        perms->apnd(tmp);
        nperm(tmp.begin(),tmp.end());
    }
    for(unsigned int i=0;i<perms->size();*ps+=*perms[i]+(i+1==perms->size()?"":"\n"),i++);
    jbyteArray r=env->NewByteArray(ps->size());
    env->SetByteArrayRegion(r,0,ps->size(),reinterpret_cast<const char*>(ps->c_str()));
    return r;
}

头文件

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_package_name_ClassName */

#ifndef _Included_com_package_name_ClassName
#define _Included_com_package_name_ClassName
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_package_name_ClassName
 * Method:    permute
 * Signature: ([B)[B
 */
JNIEXPORT jbyteArray JNICALL Java_com_package_name_ClassName_permute
  (JNIEnv *, jclass, jbyteArray);

#ifdef __cplusplus
}
#endif
#endif

应该是

对于 c: jbyte*bt = (*env)->GetByteArrayElements(env,ba,&cp);

对于 C++:jbyte*bt = env->GetByteArrayElements(ba,&cp);

GetByteArrayElements() 不是独立函数,就像您的代码试图将其用作一样。它实际上是给你的 JNIEnv 对象的成员,就像 GetArrayLength()NewByteArray()SetByteArrayRegion() 成员一样。请read the JNI documentation

您还泄漏了您分配的所有内存。根本不需要使用 new,让编译器为您管理所有内存。当你完成访问它的元素时,你需要释放 Java 字节数组。

尝试更像这样的东西:

#include <algorithm>
#include <string>
#include <vector>
#include <jni.h>
#include "com_package_name_ClassName.h"

#define apnd push_back
#define nperm std::next_permutation
typedef std::vector<std::string> slist;

JNIEXPORT jbyteArray JNICALL Java_com_package_name_ClassName_permute(JNIEnv *env, jclass cls, jbyteArray ba)
{
    jbyte *bt = env->GetByteArrayElements(ba, NULL);
    if (!bt) return NULL;
    std::string str(reinterpret_cast<char*>(bt), env->GetArrayLength(ba));
    env->ReleaseByteArrayElements(ba, bt, 0);
    std::string tmp = str;
    slist perms;
    do {
        perms.apnd(tmp);
        nperm(tmp.begin(), tmp.end());
    }
    while (tmp != str);
    std::string ps = perms[0];
    for(size_t i = 1; i < perms.size(); ++i) {
        ps += ("\n" + perms[i]);
    }
    jbyteArray r = env->NewByteArray(ps.size());
    if (r) {
        env->SetByteArrayRegion(r, 0, ps.size(), reinterpret_cast<const jbyte*>(ps.c_str()));
    }
    return r;
}