运行C++;使用JavaCPP在javaandroid应用程序中编写代码
对于Android的开发,我是一个初学者,我正在努力理解。我想在运行C++;使用JavaCPP在javaandroid应用程序中编写代码,java,c++,android-ndk,javac,javacpp,Java,C++,Android Ndk,Javac,Javacpp,对于Android的开发,我是一个初学者,我正在努力理解。我想在Android应用程序中从Java执行C++函数。在我的示例中,我只使用一个简单的TextView小部件,它打印我从C++收到的内容。 在文档之后,在应用程序的build.gradle中,我包含了我的javacpp库依赖项 dependencies { implementation 'org.bytedeco:javacpp:1.5.4' } 以便在我的应用程序中使用它。我在一个本地C++的Android Studio模板
Android
应用程序中从Java
执行C++
函数。在我的示例中,我只使用一个简单的TextView
小部件,它打印我从C++
收到的内容。
在文档之后,在应用程序的build.gradle
中,我包含了我的javacpp
库依赖项
dependencies {
implementation 'org.bytedeco:javacpp:1.5.4'
}
以便在我的应用程序中使用它。我在一个本地C++的Android Studio模板项目中测试。
我已将完整项目上传到GitHub以供参考:
此外,下面是我认为需要注意的项目中的相关文件:
NativeLibrary.java:
package com.example.javacplusplus;
import org.bytedeco.javacpp.*;
import org.bytedeco.javacpp.annotation.*;
@Platform(include="NativeLibrary.h")
@Namespace("NativeLibrary")
public class NativeLibrary {
public static class NativeClass extends Pointer {
static { Loader.load(); }
public NativeClass() { allocate(); }
private native void allocate();
// to call the getter and setter functions
public native @StdString String get_property();
public native void set_property(String property);
// to access the member variable directly
public native @StdString String property();
public native void property(String property);
}
}
#ifndef NATIVELIBRARY_H
#define NATIVELIBRARY_H
#include <string>
namespace NativeLibrary {
class NativeClass {
public:
const std::string& get_property();
void set_property(const std::string& property);
std::string property;
};
}
#endif // NATIVELIBRARY_H
#include "NativeLibrary.h"
namespace NativeLibrary {
const std::string& NativeClass::get_property() { return property; }
void NativeClass::set_property(const std::string& property) { this->property = property; }
} // namespace NativeLibrary
cmake_minimum_required(VERSION 3.4.1)
add_library(
native-lib
SHARED
NativeLibrary.cpp
native-lib.cpp)
find_library(
log-lib
log)
target_link_libraries(
native-lib
${log-lib})
package com.example.javacplusplus;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Pointer objects allocated in Java get deallocated once they become unreachable,
// but C++ destructors can still be called in a timely fashion with Pointer.deallocate()
NativeLibrary.NativeClass l = new NativeLibrary.NativeClass();
l.set_property("Hello World!");
// Example of a call to a native method
TextView tv = findViewById(R.id.sample_text);
tv.setText(l.property());
// tv.setText(stringFromJNI());
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
}
国家图书馆.h:
package com.example.javacplusplus;
import org.bytedeco.javacpp.*;
import org.bytedeco.javacpp.annotation.*;
@Platform(include="NativeLibrary.h")
@Namespace("NativeLibrary")
public class NativeLibrary {
public static class NativeClass extends Pointer {
static { Loader.load(); }
public NativeClass() { allocate(); }
private native void allocate();
// to call the getter and setter functions
public native @StdString String get_property();
public native void set_property(String property);
// to access the member variable directly
public native @StdString String property();
public native void property(String property);
}
}
#ifndef NATIVELIBRARY_H
#define NATIVELIBRARY_H
#include <string>
namespace NativeLibrary {
class NativeClass {
public:
const std::string& get_property();
void set_property(const std::string& property);
std::string property;
};
}
#endif // NATIVELIBRARY_H
#include "NativeLibrary.h"
namespace NativeLibrary {
const std::string& NativeClass::get_property() { return property; }
void NativeClass::set_property(const std::string& property) { this->property = property; }
} // namespace NativeLibrary
cmake_minimum_required(VERSION 3.4.1)
add_library(
native-lib
SHARED
NativeLibrary.cpp
native-lib.cpp)
find_library(
log-lib
log)
target_link_libraries(
native-lib
${log-lib})
package com.example.javacplusplus;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Pointer objects allocated in Java get deallocated once they become unreachable,
// but C++ destructors can still be called in a timely fashion with Pointer.deallocate()
NativeLibrary.NativeClass l = new NativeLibrary.NativeClass();
l.set_property("Hello World!");
// Example of a call to a native method
TextView tv = findViewById(R.id.sample_text);
tv.setText(l.property());
// tv.setText(stringFromJNI());
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
}
CMakeLists.txt:
package com.example.javacplusplus;
import org.bytedeco.javacpp.*;
import org.bytedeco.javacpp.annotation.*;
@Platform(include="NativeLibrary.h")
@Namespace("NativeLibrary")
public class NativeLibrary {
public static class NativeClass extends Pointer {
static { Loader.load(); }
public NativeClass() { allocate(); }
private native void allocate();
// to call the getter and setter functions
public native @StdString String get_property();
public native void set_property(String property);
// to access the member variable directly
public native @StdString String property();
public native void property(String property);
}
}
#ifndef NATIVELIBRARY_H
#define NATIVELIBRARY_H
#include <string>
namespace NativeLibrary {
class NativeClass {
public:
const std::string& get_property();
void set_property(const std::string& property);
std::string property;
};
}
#endif // NATIVELIBRARY_H
#include "NativeLibrary.h"
namespace NativeLibrary {
const std::string& NativeClass::get_property() { return property; }
void NativeClass::set_property(const std::string& property) { this->property = property; }
} // namespace NativeLibrary
cmake_minimum_required(VERSION 3.4.1)
add_library(
native-lib
SHARED
NativeLibrary.cpp
native-lib.cpp)
find_library(
log-lib
log)
target_link_libraries(
native-lib
${log-lib})
package com.example.javacplusplus;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Pointer objects allocated in Java get deallocated once they become unreachable,
// but C++ destructors can still be called in a timely fashion with Pointer.deallocate()
NativeLibrary.NativeClass l = new NativeLibrary.NativeClass();
l.set_property("Hello World!");
// Example of a call to a native method
TextView tv = findViewById(R.id.sample_text);
tv.setText(l.property());
// tv.setText(stringFromJNI());
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
}
注意NATIVE-LIB CPP只是模板中使用的C++文件,我现在忽略它。 build.gradle(对应于
应用程序
模块):
MainActivity.java:
package com.example.javacplusplus;
import org.bytedeco.javacpp.*;
import org.bytedeco.javacpp.annotation.*;
@Platform(include="NativeLibrary.h")
@Namespace("NativeLibrary")
public class NativeLibrary {
public static class NativeClass extends Pointer {
static { Loader.load(); }
public NativeClass() { allocate(); }
private native void allocate();
// to call the getter and setter functions
public native @StdString String get_property();
public native void set_property(String property);
// to access the member variable directly
public native @StdString String property();
public native void property(String property);
}
}
#ifndef NATIVELIBRARY_H
#define NATIVELIBRARY_H
#include <string>
namespace NativeLibrary {
class NativeClass {
public:
const std::string& get_property();
void set_property(const std::string& property);
std::string property;
};
}
#endif // NATIVELIBRARY_H
#include "NativeLibrary.h"
namespace NativeLibrary {
const std::string& NativeClass::get_property() { return property; }
void NativeClass::set_property(const std::string& property) { this->property = property; }
} // namespace NativeLibrary
cmake_minimum_required(VERSION 3.4.1)
add_library(
native-lib
SHARED
NativeLibrary.cpp
native-lib.cpp)
find_library(
log-lib
log)
target_link_libraries(
native-lib
${log-lib})
package com.example.javacplusplus;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Pointer objects allocated in Java get deallocated once they become unreachable,
// but C++ destructors can still be called in a timely fashion with Pointer.deallocate()
NativeLibrary.NativeClass l = new NativeLibrary.NativeClass();
l.set_property("Hello World!");
// Example of a call to a native method
TextView tv = findViewById(R.id.sample_text);
tv.setText(l.property());
// tv.setText(stringFromJNI());
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
}
应用程序构建良好,但在运行时在nativellibrary.NativeClass l=new nativellibrary.NativeClass()内崩溃代码>,带有消息无法找到“libjniationallibrary.so”
这是我的崩溃日志:
--------- beginning of crash
2020-11-16 00:57:38.557 13506-13506/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.javacppapp, PID: 13506
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/base.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_dependencies_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_resources_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_0_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_1_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_2_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_3_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_4_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_5_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_6_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_7_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_8_apk.apk", zip file "/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/base.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_dependencies_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_resources_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_0_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_1_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_2_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_3_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_4_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_5_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_6_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_7_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_8_apk.apk!/lib/x86, /data/app/com.example.javacppapp-8V-wRac6X4RLpYvvYEmtGQ==/split_lib_slice_9_apk.apk!/lib/x86, /system/lib]]] couldn't find "libjniNativeLibrary.so"
at java.lang.Runtime.loadLibrary0(Runtime.java:1012)
at java.lang.System.loadLibrary(System.java:1669)
at org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:1683)
at org.bytedeco.javacpp.Loader.load(Loader.java:1300)
at org.bytedeco.javacpp.Loader.load(Loader.java:1123)
at com.example.javacppapp.NativeLibrary$NativeClass.<clinit>(NativeLibrary.java:10)
at com.example.javacppapp.MainActivity.onCreate(MainActivity.java:22)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
2020-11-16 00:57:38.557 13506-13506/? E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
产量
$ javac -cp javacpp.jar NativeLibrary.java
$ java -jar javacpp.jar NativeLibrary
$ java -cp javacpp.jar NativeLibrary
$ Hello World!
是你好,世界代码>所以它工作正常。但我不知道为什么它在Android应用程序中不起作用
有人能帮我吗?有人知道为什么它找不到libjniationalLibrary.so
?为了完成设置,我是否需要添加一些内容?可能是libjniationallibrary。所以需要以某种方式生成
编辑1:
我已经将Build Plugin
和Platform Plugin
添加到项目的Build.gradle
文件中;现在的情况是这样的:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:4.1.1"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
plugins {
id 'java-library'
id 'java-gradle-plugin'
id 'org.bytedeco.gradle-javacpp-build' version "$javacppVersion"
id 'org.bytedeco.gradle-javacpp-platform' version "$javacppVersion"
}
ext {
javacppPlatform = 'android-arm64' // or any other platform, defaults to Loader.getPlatform()
}
dependencies {
implementation gradleApi()
api "org.bytedeco:javacpp:$javacppVersion"
}
allprojects {
repositories {
google()
jcenter()
}
}
// Note: Had to comment this as I was getting the error > Cannot add task 'clean' as a task with that name already exists.
//task clean(type: Delete) {
// delete rootProject.buildDir
//}
tasks.withType(org.bytedeco.gradle.javacpp.BuildTask) {
// set here default values for all build tasks below, typically just includePath and linkPath,
// but also properties to set the path to the NDK and its compiler in the case of Android
}
javacppBuildCommand {
// typically set here the buildCommand to the script that fills up includePath and linkPath
}
javacppBuildParser {
// typically set here the classOrPackageNames to class names implementing InfoMap
}
javacppBuildCompiler {
// typically set here boolean flags like copyLibs
}
项目同步时不会出现错误,但当我运行它时,我会得到:
> Task :javacppBuildParser FAILED
Execution failed for task ':javacppBuildParser'.
> app/build/intermediates/javac/debug/classes/com/example/myjavacppapp/BuildConfig (wrong name: com/example/myjavacppapp/BuildConfig)
是因为我没有在javacppBuildCommand
、javacppBuildParser
和javacppBuildParser
中编写任何内容吗?
我知道这是一个基本问题,但有人知道我应该在这些块中写些什么吗?我对这个很陌生,我不知道在哪里可以找到这些信息
编辑2:
在尝试了上面的编辑1中介绍的解决方案后,我看到了wiki页面,并按照那里的说明将其添加到我的应用程序的build.gradle
文件中:
import org.bytedeco.javacpp.*;
import org.bytedeco.javacpp.annotation.*;
@Platform(include="NativeLibrary.h")
@Namespace("NativeLibrary")
public class NativeLibrary {
public static class NativeClass extends Pointer {
static { Loader.load(); }
public NativeClass() { allocate(); }
private native void allocate();
// to call the getter and setter functions
public native @StdString String get_property();
public native void set_property(String property);
// to access the member variable directly
public native @StdString String property();
public native void property(String property);
}
public static void main(String[] args) {
// Pointer objects allocated in Java get deallocated once they become unreachable,
// but C++ destructors can still be called in a timely fashion with Pointer.deallocate()
NativeClass l = new NativeClass();
l.set_property("Hello World!");
System.out.println(l.property());
}
}
android {
applicationVariants.all { variant ->
variant.javaCompiler.doLast {
println 'javacpp ' + variant.name
javaexec {
main 'org.bytedeco.javacpp.tools.Builder'
classpath '/home/jacob/Work/other/sandbox/java/javacpp3/app/libs/javacpp.jar'
args '-cp', variant.javaCompiler.destinationDir,
'-properties', 'android-arm',
'-Dplatform.root=/home/jacob/.android/sdk/ndk/21.1.6352462',
'-Dplatform.compiler=/home/jacob/.android/sdk/ndk/21.1.6352462/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++',
'-Dplatform.includepath=/home/jacob/.android/sdk/ndk/21.1.6352462/sources/cxx-stl/gnu-libstdc++/include:src/main/cpp',
'-Dplatform.linkpath=/home/jacob/.android/sdk/ndk/21.1.6352462/sources/cxx-stl/llvm-libc++/libs/arm64-v8a',
'-d', 'libs/armeabi'
}
println 'javacpp done'
}
}
sourceSets.main {
jniLibs.srcDir 'libs'
jni.srcDirs = [] // disable automatic ndk-build call
}
}
gradle同步运行正常,但当我构建项目时,我得到:
> Task :app:compileDebugJavaWithJavac FAILED
javacpp debug
Exception in thread "main" java.lang.NoClassDefFoundError: androidx/appcompat/app/AppCompatActivity
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at org.bytedeco.javacpp.tools.UserClassLoader.findClass(UserClassLoader.java:72)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at org.bytedeco.javacpp.tools.ClassScanner.addClass(ClassScanner.java:61)
at org.bytedeco.javacpp.tools.ClassScanner.addMatchingFile(ClassScanner.java:75)
at org.bytedeco.javacpp.tools.ClassScanner.addMatchingDir(ClassScanner.java:87)
at org.bytedeco.javacpp.tools.ClassScanner.addMatchingDir(ClassScanner.java:85)
at org.bytedeco.javacpp.tools.ClassScanner.addMatchingDir(ClassScanner.java:85)
at org.bytedeco.javacpp.tools.ClassScanner.addMatchingDir(ClassScanner.java:85)
at org.bytedeco.javacpp.tools.ClassScanner.addPackage(ClassScanner.java:99)
at org.bytedeco.javacpp.tools.Builder.classesOrPackages(Builder.java:672)
at org.bytedeco.javacpp.tools.Builder.main(Builder.java:962)
Caused by: java.lang.ClassNotFoundException: androidx.appcompat.app.AppCompatActivity
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at org.bytedeco.javacpp.tools.UserClassLoader.findClass(UserClassLoader.java:72)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 23 more
FAILURE: Build failed with an exception.
* Where:
Build file '/home/jacob/Work/other/sandbox/java/javacpp3/app/build.gradle' line: 48
* What went wrong:
Execution failed for task ':app:compileDebugJavaWithJavac'.
> Process 'command '/home/jacob/.android/studio/jre/bin/java'' finished with non-zero exit value 1
你知道我如何解决这个问题吗?我在这里发布了一个完整的工作示例:
作为参考,我们可以通过以下步骤复制此项目:
按照
在app/build.gradle
文件中添加如下内容(以通常方式应用org.bytedeco.gradle javacpp build
插件之后),以及
更新CMakeLists.txt
文件以包含生成的.cpp
文件
我看不出你在哪里调用JavaCPP生成器?类似这样的话:@SamuelAudet非常感谢您的回答和建议!我已尝试添加构建插件
和平台插件
,请检查我对上述问题的编辑1更新?请您帮助我理解它失败的原因,以及我应该在javacppBuildCommand
、javacppBuildParser
和javacppBuildParser
中放置什么。我知道这可能是一些基本的东西,但我才刚刚开始了解Gradle,我不知道在哪里可以找到这些具体的信息。非常感谢你!这里有一个工作的例子:顺便说一句,这里有人似乎让它工作没有任何问题:请尝试联系他们,看看他们是否准备好发布代码!Thanks@HarshSavergaonkar非常感谢你的回答。是的,我知道JNI为桥接C++和java提供的机制,我知道如何使用它们。但是,它们没有提供JavaCPP提供的易用性。使用Javapp,您可以拥有直接在Java中实现的C++接口,这在维护性方面非常有用。例如,我正在寻找一个简单的Android示例,在其中我可以在java中实现C++ java函数。