[英]Android NDK C++ JNI (no implementation found for native…)
我正在尝试将 NDK 与 C++ 一起使用,但似乎无法获得正确的方法命名约定。 我的本地方法如下:
extern "C" {
JNIEXPORT void JNICALL Java_com_test_jnitest_SurfaceRenderer_drawFromJni
(JNIEnv* env, jclass c)
{
//
}
}
带有用 extern "C" {} 包裹的标头。
一切都编译正常,创建了一个 .so 文件并复制到我的项目下的 libs 文件夹,但是当我在 Eclipse 中调试和运行时,我不断收到一条日志消息“没有找到本机的实现......”。 由于所有 NDK 示例都在 C 中,我是否遗漏了什么?
谢谢。
有几件事可能会导致“找不到实现”。 一个是函数原型名称错误,另一个是根本无法加载 .so。 您确定在使用该方法之前调用了System.loadLibrary()
吗?
如果您没有定义JNI_OnLoad
函数,您可能想要创建一个并让它吐出一条日志消息,以验证该库是否已成功拉入。
你已经避开了最常见的问题——忘记使用extern "C"
——所以它要么是上面的,要么是一些轻微的拼写错误。 Java 声明是什么样的?
此错误的另一个原因:未修饰的本机方法名称不得包含下划线!
例如,我想导出一个名为AudioCapture_Ping()
的 C 函数。 这是我在 C 中的出口申报单:
JNI_EXPORT int Java_com_obsidian_mobilehashhost_MainActivity_AudioCapture_Ping(JNIEnv *pJniEnv, jobject object); //Notice the underscore before Ping
这是我导入函数的 Java 类:
package com.obsidian.mobileaudiohashhost;
...
public class MainActivity extends Activity {
private native int AudioCapture_Ping(); // FAILS
...
在删除下划线之前,我无法让 Android 动态链接到我的本机方法:
JNI_EXPORT int Java_com_obsidian_mobilehashhost_MainActivity_AudioCapturePing(JNIEnv *pJniEnv, jobject object);
package com.obsidian.mobileaudiohashhost;
...
public class MainActivity extends Activity {
private native int AudioCapturePing(); // THIS WORKS!
...
我遇到了同样的问题,但对我而言,错误出在文件 Android.mk 中。 我有它:
LOCAL_SRC_FILES := A.cpp
LOCAL_SRC_FILES := B.cpp
但应该有这个:
LOCAL_SRC_FILES := A.cpp
LOCAL_SRC_FILES += B.cpp
请注意细节+=代替:=
我希望这有帮助。
按照自动生成的 Studio 示例中提供的方式调用 extern "C",但忘记将文件的整个其余部分(包括以下函数)包装在 {} 括号中。 只有第一个功能起作用。
另一个原因:在 android.mk 中使用 LOCAL_WHOLE_STATIC_LIBRARIES 而不是 LOCAL_STATIC_LIBRARIES。 这会阻止库优化未使用的 API 调用,因为 NDK 无法从 Java 代码中检测到本机绑定的使用。
如果你的包名包含_字符,你应该在_字符后写1(一),如下所示:
主活动.java
package com.example.testcpp_2;
本机-lib.cpp
JNICALL
Java_com_example_testcpp_12_MainActivity_stringFromJNI(
使用 javah(Java SDK 的一部分)。 它正是为此的工具(从 .class 文件生成 .h 头文件)。
我尝试了以上所有解决方案,但没有人可以解决我的构建错误(jni java.lang.UnsatisfiedLinkError: No implementation found for...),最后我发现我忘记将我的 verify.cpp 源文件添加到 CMakeList.txt add_library 段(verify.cpp 是通过 Ctrl + Enter 快捷键自动生成的,也许是其他文件名),希望我的回答可以帮助一些人。
我的构建环境:Gradle + CMake
我遇到了同样的问题,在我的情况下,原因是我在包名称“RFID_Test”中有下划线,我重命名了包并且它起作用了。 感谢用户1222021
我两次遇到同样的问题。 碰巧的是,我尝试从 Android Studio 启动应用程序的手机使用了我尚未在 Android Studio 中下载的API 级别。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.