错误:未知类型名称"类对象"
error: unknown type name 'ClassObject'
我正试图用android本地代码替换android系统调用我的自定义方法,通过谷歌我发现了几个博客,但在尝试给定代码时我得到错误。
通过关注博客
我正在创建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
请帮帮我。
您得到的错误是由编译器无法找到您在应用程序中包含的符号的有效定义引起的。最可能的原因是您忘记在实现代码中包含jni.h
。
#include <jni.h>
也要确保jni.h
文件位于include-path
上(一旦添加了上面的行)。如果你已经包含了它,但是你的编译器找不到它,那么你的错误会提示
jni.h
包含在Oracle的JDK包中。你可能需要一个特定于Android使用的JVM。
编辑
你试图使用的符号不是JNI符号…我想的是jclass
。ClassObject
是Dvorak虚拟机中class
的内部表示。从这里:
在Dalvik上,所有Java类/对象到本机C结构的映射都发生在vm/oo/*文件中。对象实例镜像为ClassObject结构,方法镜像为methods。因此,每个ClassObject都有一个2d虚函数数组,它只是包含指向方法的指针。
所以你需要包括Dvorak VM头从vm/oo/
。您正在尝试直接操作虚拟机的内部。你可能应该再读一遍那篇文章,以确保你掌握了所有的内容。
我遇到了同样的问题。我被困在这一点上,当编译c库我得到这些错误说ClassObject没有找到等。所以我深入挖掘,发现这些头文件object.h和class.h以前是vm/oo目录的一部分,直到android Kitkat。当Dalvik VM几乎被掩埋时,这些文件在Lollipop发布前后被删除。
正如你可能已经发现的那样,在android中swizelling方法是非常困难的,如果你有任何替代方法,那么不值得花时间。我还没有找到在ART上这样做的方法,所以如果你遇到任何- 如何在C++中循环访问未知对象方法?
- C++:将未知类型的对象存储为成员变量的类
- 未知大小的数组作为类成员,用于在运行时(对象创建时间)创建数组的对象
- 将向量项传递给具有未知数量参数的函数对象
- C++中的自由定理:模板是否本质上对未知类型的对象无知和中立?
- 未知的 C++ 对象实例化语法
- std::vector 如何支持未知大小的自定义对象的连续内存
- 在 Duktape 中迭代未知对象
- 未知EABI对象属性44
- qt qfiledialog创建未知的com对象和安全性
- C++派生类的设置属性到从同一基类派生的未知类对象
- 创建未知数量的对象,每个对象在运行时 c++ 具有特定的对象名称
- 未知数量的对象的 CIN
- 使用以前未知的模板存储通用对象
- 如何在对象类型未知时实现交换函数
- 类成员是类型未知的派生对象
- 对象类型在编译时怎么可能是未知的
- 在编译时使用类型未知的对象初始化
- Swig-存储未知对象,直到下次调用C++函数
- 由于未知原因,在void函数中创建(大)对象失败