GetByteArrayElements не был объявлен в этой области - PullRequest
0 голосов
/ 02 июля 2019

Я пытаюсь создать нативный метод в Java с использованием C ++.Тем не менее, мой g ++ компилятор постоянно говорит мне, что моя функция GetByteArrayElements не объявлена.Я включил jni.h и соответствующий заголовочный файл в свой класс, я не знаю, что не так.Пожалуйста, помогите мне.

Я попытался изменить аргументы, чтобы увидеть, если это была проблема.Не было, поставить 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

Ответы [ 2 ]

2 голосов
/ 02 июля 2019

GetByteArrayElements() не является отдельной функцией, как ваш код пытается использовать ее как.На самом деле он является членом объекта JNIEnv, который вам дан, так же, как члены GetArrayLength(), NewByteArray() и SetByteArrayRegion().Пожалуйста, прочитайте документацию JNI .

Вы также теряете всю выделенную память.Нет необходимости использовать 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;
}
1 голос
/ 02 июля 2019

должно быть

Для с: jbyte*bt = (*env)->GetByteArrayElements(env,ba,&cp);

Для с ++: jbyte*bt = env->GetByteArrayElements(ba,&cp);

...