【问题标题】:How to call Java methods from C++ in JNI如何在 JNI 中从 C++ 调用 Java 方法
【发布时间】:2010-10-10 20:31:38
【问题描述】:

所以我正在编写一个使用大型 c++ 库的 Android 应用程序。我的一切工作正常,以便 java 应用程序可以调用 c++ 委托方法,但我发现自己希望我可以将来自 c++ 的消息记录到 Android 日志中。这从java很容易,但我不知道如何从c++调用java方法。我的搜索找到了从 c++ 打开 jvm 的方法,这根本不是我想做的。理想情况下,我想将一个 log 方法指针传递给 c++,然后可以随时使用它。当然,java 不支持方法指针。我的 java 方法看起来像:

private void log(String s){
   Log.i(Tag, s);     // Android log
}

我只是不知道如何让 c++ 访问这个方法。

【问题讨论】:

标签: java c++ android java-native-interface android-ndk


【解决方案1】:

coutprintf 的C++ 调用不会在LogCat 输出中显示。有两种解决方案。

  1. 使用 NDK 提供的 Logging 宏,允许您将消息记录到 LogCat。这对于您正在编写的新代码和包装器代码很有用,但当您拥有一个充满现有调试语句的库时就不那么好了。我将宏定义如下:

    #define LOG_INFO(info) __android_log_write(ANDROID_LOG_INFO,"JNI",info)
    #define LOG_ERROR(error) __android_log_write(ANDROID_LOG_ERROR,"JNI",error)
    

    然后在源代码中我可以调用LOG_INFO("Library is called!");

  2. 捕获程序的标准输出/标准错误并将其汇集到 LogCat。来自Android Debug Bridge 页面:

    查看标准输出和标准错误

    默认情况下,Android 系统将 stdout 和 stderr(System.out 和 System.err)输出发送到 /dev/null。在运行 Dalvik VM 的进程中,您可以让系统将输出的副本写入日志文件。在这种情况下,系统使用日志标签 stdout 和 stderr 将消息写入日志,两者的优先级均为 I。

    要以这种方式路由输出,您需要停止正在运行的模拟器/设备实例,然后使用 shell 命令 setprop 启用输出重定向。以下是你的做法:

      $ adb shell stop
      $ adb shell setprop log.redirect-stdio true
      $ adb shell start
    

    系统会保留此设置,直到您终止模拟器/设备实例。要将设置用作模拟器/设备实例的默认设置,您可以在设备上的 /data/local.prop 中添加一个条目。

【讨论】:

  • 这正是我想要的。我在模拟器上的 /data/ 文件夹中添加了一个“local.prop”文件:log.redirect-stdio=true 我正在将标准输出写入日志。
【解决方案2】:

日志记录放置在“#include”头文件中。

要链接 .so,请将 'LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog' 放在您的 make 文件中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-15
    相关资源
    最近更新 更多