这是我出错的地方。我正确加载了 opencv 库,但出现此错误。如果我进入 ximgproc,所有 native 方法都被红色标记为“无法解析相应的 jni 函数名称_函数”。我该如何解决?
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri uri = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
//Log.i("prova",uri.toString());
ImageView imageView = (ImageView) findViewById(R.id.imageView);
// imageView.setImageBitmap(bitmap);
Mat g=new Mat(bitmap.getHeight(),bitmap.getWidth(), CvType.CV_8UC1);
Utils.bitmapToMat(bitmap,g,true);
SuperpixelSLIC x=Ximgproc.createSuperpixelSLIC(g,Ximgproc.SLIC,100,3);
} catch (IOException e) {
e.printStackTrace();
}
}
}
这是我得到的错误:
06-07 19:24:01.370 21090-21090/com.example.jt1995.provaemo E/art: No implementation found for long org.opencv.ximgproc.Ximgproc.createSuperpixelSLIC_0(long, int, int, float) (tried Java_org_opencv_ximgproc_Ximgproc_createSuperpixelSLIC_10 and Java_org_opencv_ximgproc_Ximgproc_createSuperpixelSLIC_10__JIIF)
06-07 19:24:01.370 21090-21090/com.example.jt1995.provaemo E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.jt1995.provaemo, PID: 21090
java.lang.UnsatisfiedLinkError: No implementation found for long org.opencv.ximgproc.Ximgproc.createSuperpixelSLIC_0(long, int, int, float) (tried Java_org_opencv_ximgproc_Ximgproc_createSuperpixelSLIC_10 and Java_org_opencv_ximgproc_Ximgproc_createSuperpixelSLIC_10__JIIF)
at org.opencv.ximgproc.Ximgproc.createSuperpixelSLIC_0(Native Method)
at org.opencv.ximgproc.Ximgproc.createSuperpixelSLIC(Ximgproc.java:452)
at com.example.jt1995.provaemo.MainActivity.onActivityResult(MainActivity.java:108)
at android.app.Activity.dispatchActivityResult(Activity.java:6303)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3818)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3865)
at android.app.ActivityThread.access$1700(ActivityThread.java:159)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1412)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5569)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:931)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:726)
最佳答案
正如我所解释的elsewhere ,不要指望 Android Studio 神奇地将 native 方法声明解析为不是在集成 externalNativeBuild 中使用 gradle 构建的库。
您可以简单地忽略此错误消息:您的 APK 仍将安装预构建库,并且本地方法将在运行时解析,即使 Android Studio 将它们标记为红色。
您可以为此方法或整个类添加 @SuppressWarnings("JniMissingFunction")
注释:
@SuppressWarnings("JniMissingFunction")
public class Ximgproc {
或为给定项目或所有项目配置这种 Lint 检查:
但这并不能解决您的运行时问题。您大概已经构建了 C++ 代码来生成一个 native 共享库,比如说它的名称是 libXimgproc-native.so。如果它被正确打包到您的 APK 中,它将被提取到 /data/app-lib/com.example.jt1995.provaemo/
(您可以使用 getContext() 检查此路径。 getApplicationInfo().nativeLibraryDir
).
您的 Java 代码应该在尝试调用 org.opencv.ximgproc.Ximgproc 类的 native 方法之前加载此库:
System.load("Ximgproc-native");
如果上述所有假设都正确,则链接器未在该库中找到实现 createSuperpixelSLIC_0 native 方法的导出函数。它尝试了 Java_org_opencv_ximgproc_Ximgproc_createSuperpixelSLIC_10
和 Java_org_opencv_ximgproc_Ximgproc_createSuperpixelSLIC_10__JIIF
。
要检查库导出了哪些方法,您可以使用 nm 工具,它是 NDK gcc 工具链的一部分。例如。在我的 Mac 上,可以在 ~/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-nm
.
运行 …nm -D Ximgproc-native.so
它将列出带有T的库的所有导出函数。
我相信您不会在此列表中找到您的功能。也许,这个名字有点不对。也许,您将 CFLAGS 设置为 -fvisibility=hidden,并且没有显式地将函数声明为 JNIEXPORT
(或 __attribute__ ((visibility ("default")))
)。也许,C++ 函数没有用 extern "C"
声明,它的名字被编译器破坏了。
如果您使用静态库 (xxx.a) 作为中间体来组装生成的共享库,您应该知道链接器可以丢弃未使用的外部函数。在这种情况下,使用 LOCAL_WHOLE_STATIC_LIBRARIES
而不是 LOCAL_STATIC_LIBRARIES
可能会有所帮助。
关于java - 无法解析相应的 jni 函数 opencv Android,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44419188/