编写并包括C++;Android JNI应用程序的类 我对使用Android NDK和JNI很有经验,但在java和C++方面都有经验。我正在尝试构造一个MWE,它表明在本地运行循环方法比在java类上运行要快。我导入了样本,转换了JNI代码,与C++兼容,并按照预期运行。

编写并包括C++;Android JNI应用程序的类 我对使用Android NDK和JNI很有经验,但在java和C++方面都有经验。我正在尝试构造一个MWE,它表明在本地运行循环方法比在java类上运行要快。我导入了样本,转换了JNI代码,与C++兼容,并按照预期运行。,android,gradle,android-ndk,java-native-interface,Android,Gradle,Android Ndk,Java Native Interface,在同一个项目中,我删除了示例代码并重新开始,但没有更改构建设置。为了比较性能,我创建了两个相同的类,它们对整数和数组执行循环操作。我有一个Java类,叫做“代码> TESTRAPHELMADS< /COD>”和“C++类(通过 .h /代码>和 .CPP< /Case>文件),称为 TestCLSASSCPP 类。这些类别如下: public class TestClassJava { // Fields private int id; private int[] array; // Co

在同一个项目中,我删除了示例代码并重新开始,但没有更改构建设置。为了比较性能,我创建了两个相同的类,它们对整数和数组执行循环操作。我有一个Java类,叫做“代码> TESTRAPHELMADS< /COD>”和“C++类(通过<代码> .h /代码>和 .CPP< /Case>文件),称为<代码> TestCLSASSCPP 类。这些类别如下:

public class TestClassJava {

// Fields
private int id;
private int[] array;


// Constructor
public TestClassJava(int start_id) { // etc...  }

// Methods
public void incrementId() { // etc... }

public void labelArray() { // etc... }

public void loop() {
    while (id < 5000000) {
        incrementId();
        labelArray();
    }
}
}
然后是
.cpp

#include "TestClassCpp.h"

// Constructor / Destructor
TestClassCpp::TestClassCpp(int start_id) { // etc... }    
TestClassCpp::~TestClassCpp() { }

// Methods
void TestClassCpp::incrementId() { // etc... }

void TestClassCpp::labelArray() { // etc... }

void TestClassCpp::loop() {
    while (id < 5000000) {
        incrementId();
        labelArray();
   }
}
nativeloper()
testclasswrapper.cpp
文件中声明为

JNIEXPORT void JNICALL
Java_com_example_jnimwe_MainActivity_nativeLooper(JNIEnv *env, jobject instance) {

// Get class
jclass cls = env->FindClass("TestClassCpp");

// Get method id of constructor
jmethodID constructor_method_id = env->GetMethodID(cls, "<init>", "(I)V" );

// Instantiate object from C++ definition
jobject jobj = env->NewObject(cls,constructor_method_id);

// Get loop method id from object
jmethodID mid = env->GetMethodID(cls,"loop","()V");

// Loop
env->CallVoidMethod(jobj,mid);

}
JNIEXPORT void JNICALL
Java_com_示例_jnimwe_main活动_nativeloper(JNIEnv*env,jobject实例){
//上课
jclass cls=env->FindClass(“TestClassCpp”);
//获取构造函数的方法id
jmethodID构造函数_method_id=env->GetMethodID(cls,”,“(I)V”);
/从C++定义实例化对象
jobject jobj=env->NewObject(cls,构造函数\方法\ id);
//从对象获取循环方法id
jmethodID mid=env->GetMethodID(cls,“loop”和“()V”);
//环路
env->CallVoidMethod(jobj,mid);
}
应用程序构建和部署了类,但找不到具有
jclass cls=env->FindClass(“TestClassCpp”)的类。我在
build.gradle
文件中添加了
moduleName
作为
testclasswrapper

错误是

JNI在应用程序中检测到错误:调用JNI GetMethodID时,在未知的抛出位置抛出挂起的异常“java.lang.ClassNotFoundException”
06-23 16:07:14.617 12131-12131/com.example.jnimwe A/art:art/runtime/check_jni.cc:64]调用GetMethodID

很明显,它不知道这门课。因此,我假设在构建时,gradle在构建库时没有包含类定义,只是从一个文件(
testclasswrapper.cpp
)构建,而不是搜索所有文件并构建和链接所有文件。在
testclasswrapper.cpp`中添加一个
#include“/TestClassCpp.h”时,该选项会变灰,因此类的定义不会以这种方式包含


据我所知,最初的
hello jni
示例使用ndk构建。类似的答案都涉及名为
Application.mk
的makefilehello jni示例中没有生成文件,因此我的示例中也没有生成文件。我如何告诉gradle构建我创建的类并将其链接到我正在加载的库中?

我不确定是否遗漏了什么,但从上面提到的内容来看,Java中似乎没有
TestClassCpp
类;这就是
env->FindClass(“TestClassCpp”)
调用试图做的事情。您是否打算在
FindClass()
调用中查找
TestClassJava
?感谢@zenzelezz的回复。很抱歉,这个问题太长,很难理解。没错,我没有java中的TestCLSASPP,我已经在C++中定义并实现了整个类。你是说
FindClass()
只查找Java类吗?在这种情况下,我如何在JNI CPP文件中实例化C++类?是的,<代码> FUNCHACKE()/<代码>,代码> java方法()/代码>等都是为了让本机代码告诉Java在java类/对象上工作。在本机代码中,您的工作方式与不使用Java时相同。在您的例子中,我假设基本上
TestClassCpp c(x);c、 loop()好的,谢谢。JNI环境显然让我对应该使用的语法感到困惑。当我用
TestClassCpp*_c=newtestclasscpp(0)替换JNI循环例程时,编译和运行良好_c->loop()nativeloper()
方法中进行任何接口调用,对@zenzelezz有什么想法?顺便说一句,如果你想把你的建议变成一个答案,如果你愿意的话,我可以接受。很难猜测为什么一个比另一个快,而看不到
incrementId()
labelArray()
,他们可能在技术上在引擎盖下进行非常不同的操作-直接比较并不一定容易。另外,您如何度量这两个类的时间?我不确定是否遗漏了什么,但从您上面提到的内容来看,您似乎没有Java中的
TestClassCpp
类;这就是
env->FindClass(“TestClassCpp”)
调用试图做的事情。您是否打算在
FindClass()
调用中查找
TestClassJava
?感谢@zenzelezz的回复。很抱歉,这个问题太长,很难理解。没错,我没有java中的TestCLSASPP,我已经在C++中定义并实现了整个类。你是说
FindClass()
只查找Java类吗?在这种情况下,我如何在JNI CPP文件中实例化C++类?是的,<代码> FUNCHACKE()/<代码>,代码> java方法()/代码>等都是为了让本机代码告诉Java在java类/对象上工作。在本机代码中,您的工作方式与不使用Java时相同。在您的例子中,我假设基本上
TestClassCpp c(x);c、 loop()好的,谢谢。JNI环境显然让我对应该使用的语法感到困惑。当我用
TestClassCpp*_c=newtestclasscpp(0)替换JNI循环例程时,编译和运行良好_c->loop()static {
    System.loadLibrary("testclasswrapper");
}

public native void nativeLooper();
JNIEXPORT void JNICALL
Java_com_example_jnimwe_MainActivity_nativeLooper(JNIEnv *env, jobject instance) {

// Get class
jclass cls = env->FindClass("TestClassCpp");

// Get method id of constructor
jmethodID constructor_method_id = env->GetMethodID(cls, "<init>", "(I)V" );

// Instantiate object from C++ definition
jobject jobj = env->NewObject(cls,constructor_method_id);

// Get loop method id from object
jmethodID mid = env->GetMethodID(cls,"loop","()V");

// Loop
env->CallVoidMethod(jobj,mid);

}