未在此范围内声明 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;
}
我正在尝试使用 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;
}