【问题标题】:Debugging JNI Code with Xcode 4 / OS X 10.6使用 Xcode 4 / OS X 10.6 调试 JNI 代码
【发布时间】:2011-07-02 20:58:04
【问题描述】:

我一直在努力找出 Windows / Visual Studio 中的脑死问题。我在 OS X 10.6 下有一个 JNI 库,我想用 Java 可执行文件调用它并在 Xcode 下调试:单步执行代码、检查 JNI 库中的变量、设置断点等。

这是一个有效的 JNI 示例,它可以从命令行正常编译和运行。如果有人能告诉我如何在 Xcode 中进行设置,我将不胜感激。理想情况下,我希望在 Xcode 中从头开始逐步说明,并根据需要从下面的代码中剪切和粘贴,从而产生可在 Xcode 4 下调试的内容,并允许我在 JNI 代码中设置断点,检查变量,查看堆栈跟踪等。

为了表示感谢,我将向第一个给我这样的指示的人发送 20 美元,如果你给我一个 Paypal 地址,我可以在我的末端复制。

提前致谢!

HelloWorld.java

class HelloWorld {
    public native String displayHelloWorld();

    static {
        System.loadLibrary("HelloWorldImp");
    }

    public static void main(String[] args) {
        System.out.println("--> "+new HelloWorld().displayHelloWorld());
    }
}

HelloWorldImp.mm

#include <stdio.h>
#include <jni.h>

#include <string>

#import <Foundation/Foundation.h>

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jstring JNICALL
Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj)
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSString* name = @"Yo Cocoa";
    std::string s = [name UTF8String];    

    jstring ret = env->NewStringUTF(s.c_str());

    [pool drain];

    return ret;
}

#ifdef __cplusplus
}
#endif

buildjni.sh

gcc -bundle -I/System/Library/Frameworks/JavaVM.framework/Headers -lstdc++ -o libHelloWorldImp.jnilib -framework Foundation HelloWorldImp.mm

【问题讨论】:

  • 由于没有人对此表示赞同,我应该补充一点,只要我自己找到解决方案并在此处发布,20 美元的报价就会到期。 :)

标签: java xcode macos objective-c++


【解决方案1】:

给你。

构建库
您可能知道 mac 上的 jni 库必须以 libFoo.jnilib 的形式命名。然后通过调用 System.loadLibrary("Foo");
从 Java 加载库 1.新建一个动态库项目。将其命名为 libSomething。这就是命名战的一半。
2. 搜索可执行扩展的目标构建设置。默认情况下,它设置为 dylib。修改为jnilib。这是命名战的后半部分。
3. 将 JavaVM 框架添加到链接框架中。这里面有 JNI 的东西。
4. 像往常一样生成你的原生头文件。
5. 将其包含在您的项目中,并创建一个相应的 .m 文件。
6. 您必须修改 jni.h 的包含路径。在 mac 上这是 &lt;JavaVM/jni.h&gt; 使用 JavaNativeFoundation 框架。我推荐后者。
7. (可选)JavaNativeFoundation 提供了许多宏和方法,这将使数据/方法与 Java/Objective-C 之间的转换变得更加容易。它没有很好的记录,但值得研究。如果您决定使用 JNF,请使用 JavaVM 框架上的空心三角形。您将看到 JNF 是一个子框架。将它拖到与 JavaVM 相同的顶层。然后你就可以开始使用它了。 import &lt;JavaNativeFoundation/JavaNativeFoundation.h&gt; 在 JNF_COCOA_ENTER 上进行 Google 搜索以查看如何使用 JNF 的示例

您现在应该能够构建一个有效的 jni 库。假设您的代码中没有错误,那么您就完成了。 ;-)

调试
我尝试了在各种网页上找到的所有东西,以使在 Xcode 下调试 JNI 工作。它有点工作,但在踩过可可电话时会挂起。但是,使用 gdb 进行调试确实 有效。如果您在 emacs 中运行 gdb,这真的不是那么糟糕。当然,缺点是你需要加快使用 emacs 和 gdb 的速度,如果你还没有的话。这是要点:
1. 使用调试符号编译您的库
2. 在加载 lib 之后,但在调用要调试的代码之前,在您的 java 调用代码中设置断点。或者,您可以在那里放置一个 showMessageDialog。任何事情都会在正确的位置阻止 java 程序。
3. 打开活动监视器并记下您的 java 程序的 pid。
4.启动emacs。如果您使用的是 Lion,那么随附的终端 emacs 应该可以工作。在 SL 上,终端 emacs 没有一些 gdb 魔法。但是,在这两种情况下,我建议您下载并使用 mac gui emacs。可用的不止一种,我使用的是我得到的here。如果您在终端中使用 emacs,您需要转到 Termina/Preferences/Settings/Keyboard 并向下看底部。有一个复选框“使用选项作为元键”。你会想要检查的。
5. 在运行 emacs 的情况下,按 M-x(选项 x)。输入 gdb 并按回车键。您会看到类似“gdb --annotate=2 xxxxxxxxxx”的内容。按退格键直到进入注释设置。输入“pid xxx”,其中 xxx 是您的 java 调用应用程序的 pid。您最终应该得到类似于“gdb --annotate=2 pid xxxx”的行。按回车键。
6. 您应该会看到 gdb 正在为您的 jni 库加载符号。
7. 现在按 M-x。键入 gdb-many-windows。按回车键。
8. 您现在应该在 emacs 中看到多个窗口。 gdb 命令窗口、局部变量、源代码等。
9. 在命令窗口中输入 break someFunctionName。按 Enter。
10. 在命令窗口中输入 cont。 (这会导致执行继续)。按回车键。
11. 现在在 java 调试器中继续,或者在 java 对话框中按 enter。
12. 您应该看到 gdb 在您的 jni 代码中命中断点。
13.学习emacs和gdb。特别要查看 gdb 中的 po 命令。
14. Bob 是你的叔叔。

享受吧!

【讨论】:

  • 不完全是我正在寻找的解决方案,但它似乎尽可能地解决了问题,并且你的努力得到了 A。如果您想收取 20 美元,请访问我的网站并向我发送带有您的 Paypal 地址的反馈消息。再次感谢。
  • 我意识到这是很久以前的事了,但是第 7 步(JavaNativeFoundation)。有人知道如何在 Xcode 9 中完成这项工作吗?对我来说是严肃的表演终结者。
猜你喜欢
  • 1970-01-01
  • 2011-12-01
  • 1970-01-01
  • 2012-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多