从本机代码调用 Dalvik Stack
Calling Dalvik Stack from native code
我将 JNI 与 Android Studio 1.5.1 一起使用,目标是 Android API 18,我的问题是:
Q.1) 如何从本地代码调用 Dalvik 内部函数?
例如,在 Android source code 中,在解释器模块中,在 stack.cpp 中,如何从本机代码调用函数 dvmDumpThreadStack(const DebugOutputTarget* target, Thread* thread)?
我似乎需要将一些文件和 link 添加到某些库中,如 answer 中所述,但我需要具体细节。例如,我需要 link 哪些文件以及我需要在我的本机代码中包含哪些文件才能成功调用 dvmDumpThreadStack 函数?
这是Andorid.md文件的内容
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyLibrary
LOCAL_SRC_FILES := MyLibrary.c
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)
Q.2) 如何使用所需的值来定义所需的参数以调用 Dalvik 内部函数?比如我在调用dvmDumpThreadStack函数之前,如何定义target和thread,以及在调用函数之前将哪些值存入其中。
一般来说,你不会。它们被称为 "internal" 函数是有原因的。
如果你真的下定决心要这样做,你可以通过dlsym()
在运行时查找地址来找到函数指针。您将需要 "mangled" 名称,您可以通过使用 nm
检查二进制文件来获得该名称。 (在代码在 4.1 或之后从 C 切换到 C++ 之前,这更容易。)您可以通过调用 [=33= 中的 dvmGetThread
函数之一,以与 VM 相同的方式获取 Thread* ](dvmGetThreadByHandle
、dvmGetThreadByThreadId
、dvmGetThreadFromThreadObject
),或者如果您对当前话题感兴趣,请调用 dvmThreadSelf()
。将其传递给 dvmDumpThread()
,这将设置 DebugOutputTarget
,因此您不必这样做。
您不需要定义 Thread* 的头文件来传递 Thread*。只需将 thread-getter 函数声明为返回 void*,并将 thread-dump 函数声明为接受 void* 参数。如果您担心 type-safety 和可移植性,请不要从应用程序调用内部 VM 函数。
有一次我真的想这样做 -- 调试一些东西,不记得是什么 -- 我实际上向 VM 添加了一个新的 extern "C"
函数,它没有参数,只是转储了当前线程的堆。这让一切变得容易多了。
我将 JNI 与 Android Studio 1.5.1 一起使用,目标是 Android API 18,我的问题是:
Q.1) 如何从本地代码调用 Dalvik 内部函数?
例如,在 Android source code 中,在解释器模块中,在 stack.cpp 中,如何从本机代码调用函数 dvmDumpThreadStack(const DebugOutputTarget* target, Thread* thread)?
我似乎需要将一些文件和 link 添加到某些库中,如 answer 中所述,但我需要具体细节。例如,我需要 link 哪些文件以及我需要在我的本机代码中包含哪些文件才能成功调用 dvmDumpThreadStack 函数?
这是Andorid.md文件的内容
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyLibrary
LOCAL_SRC_FILES := MyLibrary.c
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)
Q.2) 如何使用所需的值来定义所需的参数以调用 Dalvik 内部函数?比如我在调用dvmDumpThreadStack函数之前,如何定义target和thread,以及在调用函数之前将哪些值存入其中。
一般来说,你不会。它们被称为 "internal" 函数是有原因的。
如果你真的下定决心要这样做,你可以通过dlsym()
在运行时查找地址来找到函数指针。您将需要 "mangled" 名称,您可以通过使用 nm
检查二进制文件来获得该名称。 (在代码在 4.1 或之后从 C 切换到 C++ 之前,这更容易。)您可以通过调用 [=33= 中的 dvmGetThread
函数之一,以与 VM 相同的方式获取 Thread* ](dvmGetThreadByHandle
、dvmGetThreadByThreadId
、dvmGetThreadFromThreadObject
),或者如果您对当前话题感兴趣,请调用 dvmThreadSelf()
。将其传递给 dvmDumpThread()
,这将设置 DebugOutputTarget
,因此您不必这样做。
您不需要定义 Thread* 的头文件来传递 Thread*。只需将 thread-getter 函数声明为返回 void*,并将 thread-dump 函数声明为接受 void* 参数。如果您担心 type-safety 和可移植性,请不要从应用程序调用内部 VM 函数。
有一次我真的想这样做 -- 调试一些东西,不记得是什么 -- 我实际上向 VM 添加了一个新的 extern "C"
函数,它没有参数,只是转储了当前线程的堆。这让一切变得容易多了。