错误:未知类型名称' ClassObject'

时间:2014-06-24 13:44:40

标签: java android c++ c android-ndk

我正在尝试用我的自定义方法使用Android本机代码替换android系统调用,通过谷歌搜索我找到了一些博客,但在尝试给定代码时我收到错误。

关注博客

我正在使用此blog

中的以下代码创建android Native方法
#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

请帮帮我。提前谢谢。

2 个答案:

答案 0 :(得分:1)

您获得的错误是由编译器无法找到您在应用程序中包含的符号的有效定义引起的。最可能的原因是您忘记在实施代码中包含jni.h

#include <jni.h>

确保jni.h文件位于include-path上(一旦添加了上述行)。如果你已经包含它但你的编译器找不到它,那么你的错误就会表明这一点。

jni.h包含在Oracle的JDK包中。您可能需要一个特定于Android使用的JVM。

修改

您尝试使用的符号不是JNI符号......我在想jclassClassObject是Dvorak虚拟机中class的内部表示。从这里开始:

  

在Dalvik上,所有Java类/对象映射到本机C结构都发生在vm / oo / *文件中。对象实例使用ClassObject结构进行镜像,使用方法进行镜像。   因此每个ClassObject都带有2d vtable数组,它只包含指向Methods的指针。

因此您需要包含来自vm/oo/的Dvorak VM标头。您正在尝试直接操作VM的内部。你应该再读一遍这篇文章,以确保你把它全部拿走了。

答案 1 :(得分:-1)

我遇到了同样的问题。我被困在这一点,当编译c库时我得到了这些错误,说没有找到ClassObject等等。所以我深挖并发现这些头文件object.h和class.h以前是vm/oo目录的一部分,直到android Kitkat。当Dalvik VM几乎被埋没时,这些文件在Lollipop发布之后及之后被删除。

你可能已经发现android中的swizelling方法非常困难,如果你有任何替代方案,那就不值得花时间了。 我还没有找到一种在ART上进行此操作的方法,所以如果您遇到任何

,请发表评论