Я не уверен, что полностью понял вашу настройку, и если вам нужно, чтобы это было сделано из eclipse или нет. Во всяком случае, мне было интересно сделать небольшую тестовую программу с использованием JNI и библиотеки Cocoa, которая ничего не делала, просто чтобы попробовать отладить код obj-c/c.
Мне удалось выполнить эту настройку, а также отладить код. Я использую IntelliJ для Java и Xcode для части objc/c, но выполнение части java в eclipse не составляет труда.
Таким образом, вы сможете точно настроить структуру моего проекта и приступить к отладке. И оттуда вы сможете применить эти знания к своему собственному более сложному коду.
Вот как я начал:
- Создайте новый проект в Xcode, выбрав Cocoa Library.
![Библиотека какао](https://i.stack.imgur.com/ZiY6S.png)
- Назовите проект
libnative
и сделайте его динамическим.
![Выберите параметры](https://i.stack.imgur.com/X2b6W.png)
Выберите место для вашего нового проекта. Я использую ~/Development/
и пропускаю часть Create local git...
.
Это создаст новый проект с именем lib native.xcodeproj
в выбранной вами папке. Были автоматически созданы два файла: libnative.h
и libnative.m
.
Сначала вы должны изменить настройки проекта.
Executable Extension
in the Packaging
section must be changed from dynlib
to jnilib
.
Framework Search Paths
в разделе Search Paths
необходимо обновить, чтобы указать на структуру JNI: /System/Library/Frameworks/JavaVM.framework/Frameworks/JavaNativeFoundation.framework/
![введите здесь описание изображения](https://i.stack.imgur.com/rU1oq.png)
- Теперь пришло время добавить немного кода. Имейте в виду, что с этой настройкой вам придется использовать
<JavaVM/jni.h>
. Обновите libnative.m
, чтобы он выглядел следующим образом:
//
// 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
com.stackoverflow.Main.java
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();
}
}
- Установите точку останова на строке перед
Main.print();
. Запустите отладчик со следующей опцией JVM:
-Djava.library.path="/Users/maba/Library/Developer/Xcode/DerivedData/libnative-cquleqohzyhghnercyqdwpnznjdf/Build/Products/Debug/"
Эта строка немного длинная и зависит от пользователя. Вам придется самим искать имена каталогов, но они будут более или менее такими же, как у меня, за исключением сгенерированного пути libnative-cquleqohzyhghnercyqdwpnznjdf
.
Программа должна быть запущена и ждать точки останова. Время подключить отладчик Xcode к работающему приложению.
Выберите меню Product
-> Attach to Process >
и укажите на запущенный процесс java
в части System
раскрывающегося списка. Если есть несколько процессов java
, то это, скорее всего, тот, у которого самый высокий PID, но не всегда. Вам придется попробовать.
Создайте точку останова в коде c на строке printf("Hello from C");
.
Вернитесь в Java IDE и продолжите выполнение с того места, где оно остановилось.
Вернитесь в Xcode и убедитесь, что он находится в точке останова!
![В точке останова](https://i.stack.imgur.com/bYka5.png)
Как я уже говорил ранее, это очень простой подход к obj-c/JNI, и ваш проект, вероятно, довольно большой, но с помощью этого небольшого тестового проекта вы можете, по крайней мере, увидеть, как он работает, а затем продолжить настройку своего собственного проекта.
09.10.2012