ошибка: неизвестное имя типа ‘ClassObject’

#java #android #c #c #android-ndk

#java #Android #c #c #android-ndk

Вопрос:

Я пытаюсь заменить системный вызов Android своим пользовательским методом, используя собственный код Android, путем поиска в Google я нашел несколько блогов, но при попытке выполнить данный код я получаю ошибки.

следуя блогу

Я создаю собственный метод Android, используя следующий код из этого блога

 #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
  

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

Комментарии:

1. где находится метод ‘g_dvmfindloadedclass’, я никогда не видел таких методов

Ответ №1:

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

 #include <jni.h>
  

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

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

Редактировать

Символы, которые вы пытаетесь использовать, не являются символами JNI … Я думал о jclass . ClassObject является внутренним представлением a class в виртуальной машине Dvorak. Отсюда:

В Dalvik все сопоставление классов / объектов Java с собственными структурами C происходит в файлах vm / oo / *. Экземпляры объектов зеркально отображаются со структурами ClassObject, а методы — с методами. Таким образом, каждый ClassObject поставляется с массивом 2d vtable, который просто содержит указатели на методы.

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

Комментарии:

1. Это может быть комментарий

2. @CasperSky @Brian Это could можно оставить в качестве комментария, но это ответ на вопрос. Я немного расширю его.

3. @IndraYadav — покажите свой код (не с веб-сайта) полностью.

4. @Dennis.. Я опубликовал код .. с нетерпением жду вашего ответа.

5. @Dennis Объект ClassObject, объявленный здесь в vm / oo/ Object.h, я попытался включить все возможные заголовочные файлы, такие как globals.h, Object.h, но не смог добиться успеха..

Ответ №2:

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

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