我在C++中使用JNI和JVMTI,目的是打印目标Java应用程序的所有类名.我遇到的问题是,当试图从每个Java类内部调用getName()方法时,它会崩溃.
static jvmtiEnv* jvmtiEnv;
static JNIEnv* Env;
// The following code is located inside a method
jint class_count;
jclass* classes_ptr;
jvmtiEnv->GetLoadedClasses(&class_count, &classes_ptr);
Logger::Log("LoadedClassCount: " + std::to_string(class_count));
for (int i = 0; i < class_count; i++) {
jclass clazz = classes_ptr[i];
if (clazz) {
//Logger::Log("Class Number: " + std::to_string(i));
jmethodID mid_getName = Env->GetMethodID(clazz, "getName", "()Ljava/lang/String;");
if (!mid_getName) continue; // This method is not always available.
Logger::Log("Pass 2");
jobject classNameObj = Env->CallObjectMethod(clazz, mid_getName); // Crashes here
if (!classNameObj) continue;
Logger::Log("Pass 3");
// Printing fix suggested by @Someprogrammerdude
std::string str = Env->GetStringUTFChars((jstring) classNameObj, 0);
Logger::Log(("ClassName: " + str).c_str()); // or Logger::Log("ClassName: " + str)
}
}
当然,jvmtiEnv和Env字段已初始化并正常工作,因为我可以调用其他方法,但似乎不知道如何打印类名.以下是我的日志(log)记录方法.我还将日志(log)方法调用打印到主动附加到目标Java应用程序的控制台,但由于代码崩溃,这部分没有用,因此我还需要打印到txt文件.
void Logger::Log(std::string message)
{
if (!Logger::Initialized) Logger::Init();
std::cout << "[ LOG ] :: " + message << std::endl;
std::ofstream log("C:\\Users\\me\\debug.txt", std::ofstream::app | std::ofstream::out);
log << message << std::endl;
}