Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 调试目标C JNI代码_Objective C_Xcode_Eclipse_Debugging_Java Native Interface - Fatal编程技术网

Objective c 调试目标C JNI代码

Objective c 调试目标C JNI代码,objective-c,xcode,eclipse,debugging,java-native-interface,Objective C,Xcode,Eclipse,Debugging,Java Native Interface,情况如下: 我在eclipse中打开了一个客户机的java项目。它使用由Xcode Objective C项目创建的JNI库。当我执行Java代码时,有什么好方法可以调试eclipse中的C代码吗?显然,eclipse的默认调试器无法进入jni库文件,我们将丢失线程(这里的线程指的是调查线程,而不是编程线程) 任何建议或输入都是值得赞赏的,因为代码库足够大,遵循客户的代码将比其他选项快得多 谢谢 编辑: 应该注意的是,jni库之所以用Objective-C编写,是因为它与MacOSX集成。它使用

情况如下:

我在eclipse中打开了一个客户机的java项目。它使用由Xcode Objective C项目创建的JNI库。当我执行Java代码时,有什么好方法可以调试eclipse中的C代码吗?显然,eclipse的默认调试器无法进入jni库文件,我们将丢失线程(这里的线程指的是调查线程,而不是编程线程)

任何建议或输入都是值得赞赏的,因为代码库足够大,遵循客户的代码将比其他选项快得多

谢谢

编辑:


应该注意的是,jni库之所以用Objective-C编写,是因为它与MacOSX集成。它使用Cocoa框架与Apple speech api集成。

您可以从终端连接
gdb
(或
lldb
)。如果使用本机代码启动进程是由
fork()/exec()
--即,如果您不能键入
gdb/some/command/line
--则您可能可以使用
--waitfor
选项(参见手册页)等待进程启动

加载符号将很棘手



这是一个使用cocoa框架的MacOSX项目。这会影响你吗 这个

不应该。如果有什么不同的话,这将使它变得更容易,希望符号文件是一种可用的格式。关键通常是在java和本机代码之间的边界上找到合适的断点

是加载到JVM的动态库中的本机代码,还是您有一个在内部启动JVM的自定义可执行文件


在任何情况下,都需要将本机调试器附加到运行该本机代码的任何进程。可能在您适当地设置了基于java的调试会话之后。

在过去进行JNI时,我已经构建了一个测试工具来促进应用程序的本机部分(以及JNI代码)的开发,这很容易出错,避免了从双方同时进行调试的需要

这是作为本机应用程序编写的,它以编程方式调用JVM,而不是从Java应用程序开始,然后尝试连接到JVM

当然,您可以启动它并在Xcode中调试它——这是使用CDT的Eclipse最好的体验


这种安排的Java端通常非常简单且不需要贡献——基本上是一种从应用程序的本机部分调用的方法,然后通过JNI将一个或多个调用返回到本机部分

我不确定我是否完全理解了您的设置,以及您是否需要从eclipse完成此操作。总之,我感兴趣的是使用JNI和Cocoa库编写一个小测试程序,什么都不做,只是为了调试obj-c/c代码

我成功地完成了这个设置并调试了代码。我对Java使用IntelliJ,对objc/c部分使用Xcode,但在eclipse中使用Java部分是不需要动脑筋的

所以您应该能够准确地设置我的项目结构并开始调试。从那里,您应该能够将这些知识应用到您自己更复杂的代码中

我是这样开始的:

  • 通过选择Cocoa库在Xcode中创建一个新项目

  • 将项目命名为
    libnative
    ,并将其设置为动态类型

  • 为新项目选择一个地点。我使用
    ~/Development/
    并跳过
    创建本地git…
    部分

  • 这将在所选文件夹中创建一个名为
    lib native.xcodeproj
    的新项目。已经自动创建了两个文件:
    libnative.h
    libnative.m

  • 首先,必须更改项目设置

    • Packaging
      部分中的
      Executable Extension
      必须从
      dynlib
      更改为
      jnilib
    • 必须更新
      搜索路径
      部分中的
      框架搜索路径
      ,以指向JNI框架:
      /System/Library/Frameworks/JavaVM.Framework/Frameworks/JavaNativeFoundation.Framework/

  • 现在是添加一些代码的时候了。请注意,使用此设置时,您必须使用
    。将
    libnative.m
    更新为如下代码:

  • Main.print()之前的行上设置断点。使用以下JVM选项启动调试器:

这一行有点长,而且是特定于用户的。您必须自己查找目录名,但除了生成的
libnative cquleqohzyhghnercyqdwpnznjdf
路径外,它们或多或少与我的相同

  • 程序应该在断点处运行并等待。将Xcode调试器附加到正在运行的应用程序的时间

  • 选择菜单
    Product
    ->
    Attach to Process>
    ,并指向下拉列表的
    System
    部分中正在运行的
    java
    进程。如果有多个
    java
    进程,那么它很可能是PID最高的进程,但并不总是如此。你得试试

  • 在c代码中的
    printf行(“Hello from c”)上创建一个断点

  • 返回JavaIDE并从停止的位置继续执行

  • 回到Xcode,看看它在断点处等待



正如我前面所说的,这是一种非常简单的obj-c/JNI方法,您的项目可能相当大,但通过这个小测试项目,您至少可以看到它是如何工作的,然后继续自己的项目设置。

以下是我在Windows下调试JNI(c/c++)的步骤,我认为ObjectiveC需要同样的步骤。对于Linux,它是
//
//  libnative.m
//  libnative
//
//  Created by maba on 2012-10-09.
//  Copyright (c) 2012 maba. All rights reserved.
//

#import "libnative.h"
#include <JavaVM/jni.h>

@implementation libnative

@end

#ifdef __cplusplus
extern "C" {
#endif

#ifndef VEC_LEN
#define VEC_LEN(v) (sizeof(v)/sizeof(v[0]))
#endif/*VEC_LEN*/

static JavaVM *javaVM;

static void print();

static JNINativeMethod Main_methods[] =
{
    { "print", "()V", (void*)print },
};

static struct {
    const char      *class_name;
    JNINativeMethod *methods;
    int             num_methods;
} native_methods[] = {
    { "com/stackoverflow/Main", Main_methods, VEC_LEN(Main_methods) },
};

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
    JNIEnv *env = 0;
    jclass cls  = 0;
    jint   rs   = 0;

    if ((*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_4)) {
        return JNI_ERR;
    }

    javaVM = jvm;

    for (unsigned int i = 0; i < VEC_LEN(native_methods); i++) {
        cls = (*env)->FindClass(env, native_methods[i].class_name);
        if (cls == NULL) {
            return JNI_ERR;
        }
        rs = (*env)->RegisterNatives(env, cls, native_methods[i].methods, native_methods[i].num_methods);
        assert(rs == JNI_OK);
    }

    return JNI_VERSION_1_4;
}

static void print(JNIEnv *env, jclass cls) {
    printf("Hello from C");
}

#ifdef __cplusplus
}
#endif
package com.stackoverflow;

/**
 * @author maba, 2012-10-09
 */
public class Main {

    static native void print();

    static {
        System.out.println(System.getProperty("java.library.path"));
        System.loadLibrary("native");
    }

    public static void main(String[] args) {
        System.out.println("Loading native");
        Main.print();
    }
}
-Djava.library.path="/Users/maba/Library/Developer/Xcode/DerivedData/libnative-cquleqohzyhghnercyqdwpnznjdf/Build/Products/Debug/"