2014-06-24 6 views
0

Я пытаюсь заменить системный вызов android с помощью своего собственного метода, используя собственный код на основе android, по поиску googling. Я нашел несколько блогов, но, пытаясь получить код, я получаю ошибки.ошибка: неизвестный тип name 'ClassObject'

следуя блога

Я Создание андроида Native метод, используя следующий код из этого blog

#include "com_appwrapping_tunneling_SimpleActivity.h" 

int Java_com_appwrapping_tunneling_SimpleActivity_swap_1virtual_1methods(char *origclass, char *origmeth, char *newclass, char *newmeth) { 
    int i = 0; 
    ClassObject *newclazz = g_dvmfindloadedclass(newclass); 
    if (!newclazz) { 
    return 0; 
    } 
    ClassObject *oldclazz = g_dvmfindclass(origclass, newclazz->classLoader); 
    if (!oldclazz) { 
    return 0; 
    } 
    struct Method *oldm = NULL, *newm = NULL; 
    if (newclazz) { 
    for (i = 0; i < newclazz->vtableCount; i++) { 
     if(!strcmp(newclazz->vtable[i]->name, newmeth)) 
      // this is the new method 
      newm = newclazz->vtable[i]; 
    } 
    } 
    if (oldclazz) { 
    for (i = 0; i < oldclazz->vtableCount; i++) { 
     if(!strcmp(oldclazz->vtable[i]->name, origmeth)) { 
      // save old method 
      oldm = oldclazz->vtable[i]; 
      // put new method in place of old 
      oldclazz->vtable[i] = newm; 
     } 
    } 
    } 
    if (!newm || !oldm) { 
    __android_log_print(ANDROID_LOG_ERROR, MYLOG_TAG, "failed to find methods/objects"); 
    return 0; 
    } 
    // add some space for original method 
    oldclazz->vtable = g_dvmlinearrealloc(oldclazz->classLoader, 
         oldclazz->vtable, 
         sizeof(*(oldclazz->vtable)) * (oldclazz->vtableCount + 1)); 
    // we put it at the end of the table 
    oldclazz->vtableCount++; 
    oldclazz->vtable[oldclazz->vtableCount - 1] = oldm; 
    // now new method gets old method name 
    newm->name = oldm->name; 
    char *fname = NULL; 
    // leaking memory here 
    fname = (char*) malloc(strlen(origmeth) + strlen(FAKE_PREFIX) + 1); 
    sprintf(fname, "%s%s", FAKE_PREFIX, origmeth); 
    // now old method will get _orig_ prefix, so it can be looked up later 
    oldm->name = fname; 
    // swap method indexes 
    newm->methodIndex = oldm->methodIndex; 
    // now old method gets proper index 
    oldm->methodIndex = oldclazz->vtableCount - 1; 
    g_dvmdumpclass(oldclazz, 1); 
    g_dvmdumpclass(newclazz, 1); 
    __android_log_write(ANDROID_LOG_DEBUG, MYLOG_TAG, "swap successful!"); 
    return 1; 
} 

Все вещи происходит нормально, но при создании .so файл, используя следующую команду:

<NDK-Home>$ ndk-build 

Я получаю следующую ошибку:

JNIApp/jni/testLib.c: In function 'swap_1virtual_1methods': 
JNIApp/jni/testLib.c:6:3: error: unknown type name 'ClassObject' 
JNIApp/jni/testLib.c:6:27: warning: initialization makes pointer from integer without a cast [enabled by default] 
JNIApp/jni/testLib.c:10:3: error: unknown type name 'ClassObject' 
JNIApp/jni/testLib.c:10:61: error: request for member 'classLoader' in something not a structure or union 
JNIApp/jni/testLib.c:14:25: error: 'NULL' undeclared (first use in this function) 
JNIApp/jni/testLib.c:14:25: note: each undeclared identifier is reported only once for each function it appears in 
JNIApp/jni/testLib.c:16:29: error: request for member 'vtableCount' in something not a structure or union 
JNIApp/jni/testLib.c:17:28: error: request for member 'vtable' in something not a structure or union 
JNIApp/jni/testLib.c:19:27: error: request for member 'vtable' in something not a structure or union 
JNIApp/jni/testLib.c:23:29: error: request for member 'vtableCount' in something not a structure or union 
JNIApp/jni/testLib.c:24:28: error: request for member 'vtable' in something not a structure or union 
JNIApp/jni/testLib.c:26:27: error: request for member 'vtable' in something not a structure or union 
JNIApp/jni/testLib.c:28:20: error: request for member 'vtable' in something not a structure or union 
JNIApp/jni/testLib.c:33:25: error: 'ANDROID_LOG_ERROR' undeclared (first use in this function) 
JNIApp/jni/testLib.c:33:44: error: 'MYLOG_TAG' undeclared (first use in this function) 
JNIApp/jni/testLib.c:37:11: error: request for member 'vtable' in something not a structure or union 
JNIApp/jni/testLib.c:37:49: error: request for member 'classLoader' in something not a structure or union 
JNIApp/jni/testLib.c:38:31: error: request for member 'vtable' in something not a structure or union 
JNIApp/jni/testLib.c:39:40: error: request for member 'vtable' in something not a structure or union 
JNIApp/jni/testLib.c:39:62: error: request for member 'vtableCount' in something not a structure or union 
JNIApp/jni/testLib.c:41:11: error: request for member 'vtableCount' in something not a structure or union 
JNIApp/jni/testLib.c:42:11: error: request for member 'vtable' in something not a structure or union 
JNIApp/jni/testLib.c:42:28: error: request for member 'vtableCount' in something not a structure or union 
JNIApp/jni/testLib.c:44:7: error: dereferencing pointer to incomplete type 
JNIApp/jni/testLib.c:44:20: error: dereferencing pointer to incomplete type 
JNIApp/jni/testLib.c:47:19: warning: incompatible implicit declaration of built-in function 'malloc' [enabled by default] 
JNIApp/jni/testLib.c:47:26: warning: incompatible implicit declaration of built-in function 'strlen' [enabled by default] 
JNIApp/jni/testLib.c:47:52: error: 'FAKE_PREFIX' undeclared (first use in this function) 
JNIApp/jni/testLib.c:48:3: warning: incompatible implicit declaration of built-in function 'sprintf' [enabled by default] 
JNIApp/jni/testLib.c:50:7: error: dereferencing pointer to incomplete type 
JNIApp/jni/testLib.c:52:7: error: dereferencing pointer to incomplete type 
JNIApp/jni/testLib.c:52:27: error: dereferencing pointer to incomplete type 
JNIApp/jni/testLib.c:54:7: error: dereferencing pointer to incomplete type 
JNIApp/jni/testLib.c:54:31: error: request for member 'vtableCount' in something not a structure or union 
JNIApp/jni/testLib.c:57:23: error: 'ANDROID_LOG_DEBUG' undeclared (first use in this function) 
make: *** [JNIApp/obj/local/armeabi-v7a/objs/testLib/testLib.o] Error 1 

Пожалуйста, помогите мне. Заранее спасибо.

+0

где не метод «g_dvmfindloadedclass», я никогда не видел методы, как этот – Charlesjean

+0

какие-либо улучшения? – guness

ответ

1

Ошибки, которые вы получаете, вызваны тем, что компилятор не смог найти правильное определение символов, которые вы включили в приложение. Наиболее вероятной причиной этого является то, что вы забыли включить jni.h в свой код реализации.

#include <jni.h> 

УБЕДИТЕСЬ, а также о том, что файл jni.h на ваш include-path (после того как вы добавили эту строку). Если бы вы включили его, но ваш компилятор не смог его найти, тогда ваша ошибка указала бы это.

jni.h включен в пакеты JDK от Oracle. Возможно, вам понадобится конкретный JVM, который использует Android.

EDIT

символы, которые вы пытаетесь использовать не JNI символы ... Я думал jclass. ClassObject - это внутреннее представление class в виртуальной машине Дворжака. Отсюда:

On Dalvik all Java class/object mapping to native C structs is happening in vm/oo/* files. Object instances are mirrored with ClassObject structs, and methods with Methods. So each ClassObject comes with 2d vtable array, which simply contains pointers to Methods.

Так что вам нужно включить все заголовки Dvorak VM от vm/oo/. Вы пытаетесь напрямую манипулировать внутренними компонентами виртуальной машины. Вам, вероятно, следует снова прочитать эту статью, чтобы убедиться, что вы все собрали.

+0

Это может быть комментарий – Devrath

+0

@CasperSky @Brian Это 'can' может быть оставлено в качестве комментария, но это ответ на вопрос. Я немного расширю его. – Dennis

+0

Спасибо за ответ .. но я уже включил jni.h –

-1

Я столкнулся с той же проблемой. Я застрял в этой точке, когда при компиляции библиотеки c я получил эти ошибки, говорящие о том, что ClassObject не найден и т. Д. Поэтому я глубоко вырыл и обнаружил, что эти файлы заголовков object.h и class.h ранее были частью каталога vm/oo до андроида Kitkat. Когда Dalvik VM был почти похоронен, эти файлы были удалены в и после Lollipop релиз.

Как вы, возможно, уже выяснили, что методы swizelling в android чрезвычайно сложны и не стоят времени, если у вас есть любые альтернативы. я не нашел способ сделать это на ART поэтому, пожалуйста, комментарий, если вы столкнулись с какой-либо

Смежные вопросы