好的...刚刚尝试过...似乎按预期工作....在现实生活中,VMInit 回调将返回一个类的实例,该实例实现了一个镜像 C JVMTI 接口的接口.... C 代理将存储此实例并在事件需要时调用它....另外,在 VMInit Java 返回之前,它会设置功能和回调并注册事件等....您可能可以获得大约 90% 的 JVMTI API覆盖范围.....这只是输入它的一个例子......如果你有一个强有力的案例,我可以在一个周末完成:-)
下面的代码产生这个:
C:VMInit,准备回调Java方法
Java:JVMTI 回调类,VMInit()。
C:VMInit,回调Java方法成功返回
Java:最后...您好,我是 Java 主力
package com.stackoverflow;
public class JVMTICallback {
public static void VMInit() {
System.out.println("Java:\tJVMTI callback class, VMInit().");
}
public static void main(String[] args) {
// This main is only here to give us something to run for the test
System.out.println("Java:\tAnd Finally... Hello, I'm the Java main");
}
}
和C
#include <stdlib.h>
#include "jvmti.h"
jvmtiEnv *globalJVMTIInterface;
void JNICALL
vmInit(jvmtiEnv * jvmti_env, JNIEnv * jni_env, jthread thread)
{
printf("C:\tVMInit, preparing to callback Java method\n");
char *className = "com/stackoverflow/JVMTICallback";
char *methodName = "VMInit";
char *descriptor = "()V";
jclass callbackClass = (*jni_env)->FindClass(jni_env, className);
if (!callbackClass) {
fprintf(stderr,"C:\tUnable to locate callback class.\n");
return;
}
jmethodID callbackMethodID = (*jni_env)->GetStaticMethodID(jni_env, callbackClass, methodName, descriptor);
if (!callbackMethodID)
{
fprintf(stderr, "C:\tUnable to locate callback VMInit method\n");
return;
}
(*jni_env)->CallStaticVoidMethodV(jni_env, callbackClass, callbackMethodID, NULL);
printf("C:\tVMInit, callback Java method returned successfully\n");
}
JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM * jvm, char *options, void *reserved)
{
jint returnCode = (*jvm)->GetEnv(jvm, (void **) &globalJVMTIInterface,
JVMTI_VERSION_1_0);
if (returnCode != JNI_OK)
{
fprintf(stderr,
"The version of JVMTI requested (1.0) is not supported by this JVM.\n");
return JVMTI_ERROR_UNSUPPORTED_VERSION;
}
jvmtiEventCallbacks *eventCallbacks;
eventCallbacks = calloc(1, sizeof(jvmtiEventCallbacks));
if (!eventCallbacks)
{
fprintf(stderr, "Unable to allocate memory\n");
return JVMTI_ERROR_OUT_OF_MEMORY;
}
eventCallbacks->VMInit = &vmInit;
returnCode = (*globalJVMTIInterface)->SetEventCallbacks(globalJVMTIInterface,
eventCallbacks, (jint) sizeof(*eventCallbacks));
if (returnCode != JNI_OK)
{
fprintf(stderr, "C:\tJVM does not have the required capabilities (%d)\n",
returnCode);
exit(-1);
}
returnCode = (*globalJVMTIInterface)->SetEventNotificationMode(
globalJVMTIInterface, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, (jthread) NULL);
if (returnCode != JNI_OK)
{
fprintf(
stderr,
"C:\tJVM does not have the required capabilities, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT (%d)\n",
returnCode);
exit(-1);
}
return JVMTI_ERROR_NONE;
}