我正在尝试学习如何使用C ++读取Java类文件。任何人都可以帮我弄清楚为什么AccessFlag打印0?它可以打印的最低值是0x00001。所以我认为我正在读取常量池表错误,但我不确定它有什么问题。有任何想法吗?我关注的是:http://www.murrayc.com/learning/java/java_classfileformat.shtml
到目前为止,我得到了:
#include <iostream>
#include <fstream>
#include <vector>
template <typename T>
T ReadPointer(char*& Pointer)
{
T Result = *(reinterpret_cast<T*>(Pointer));
Pointer += sizeof(T);
return Result;
}
struct ConstantPool
{
int type;
std::string name;
ConstantPool* arg1;
ConstantPool* arg2;
short index1, index2;
std::string strValue;
int intValue;
std::int64_t longValue;
float floatValue;
double doubleValue;
ConstantPool() {}
ConstantPool(char* &Pointer) {this->Read(Pointer);}
void Read(char* &Pointer);
};
void ConstantPool::Read(char* &Pointer)
{
switch(type = static_cast<int>(ReadPointer<std::uint8_t>(Pointer)))
{
case 1:
{
name = "Ascii";
int Length = ReadPointer<short>(Pointer);
while (Length > 0)
{
char C = ReadPointer<char>(Pointer);
strValue += C;
Length--;
}
}
break;
case 2:
{
name = "Unicode";
int Length = ReadPointer<short>(Pointer);
while (Length > 0)
{
char C = ReadPointer<char>(Pointer);
strValue += C;
Length--;
}
}
break;
case 3:
name = "Int";
intValue = ReadPointer<double>(Pointer);
break;
case 4:
name = "Float";
floatValue = ReadPointer<float>(Pointer);
break;
case 5:
name = "Long";
longValue = ReadPointer<long>(Pointer);
break;
case 6:
name = "Double";
doubleValue = ReadPointer<double>(Pointer);
break;
case 7:
name = "Class";
index1 = ReadPointer<short>(Pointer);
index2 = -1;
break;
case 8:
name = "String";
index1 = ReadPointer<short>(Pointer);
index2 = -1;
break;
case 9:
name = "Field Reference";
index1 = ReadPointer<short>(Pointer);
index2 = ReadPointer<short>(Pointer);
break;
case 10:
name = "Method Reference";
index1 = ReadPointer<short>(Pointer);
index2 = ReadPointer<short>(Pointer);
break;
case 11:
name = "Interface Reference";
index1 = ReadPointer<short>(Pointer);
index2 = ReadPointer<short>(Pointer);
break;
case 12:
name = "Name And Type";
index1 = ReadPointer<short>(Pointer);
index2 = ReadPointer<short>(Pointer);
break;
}
}
typedef struct
{
int MagicNumber;
short MinorVersion;
short MajorVersion;
short ConstantPoolCount;
} ClassFile;
int main()
{
std::fstream File("Animal.class", std::ios::in | std::ios::binary);
if (File.is_open())
{
File.seekg(0, std::ios::end);
std::vector<std::uint8_t> Data(File.tellg());
char* Ptr = reinterpret_cast<char*>(&Data[0]);
File.seekg(0, std::ios::beg);
File.read(Ptr, Data.size());
/**Check Magic Number.**/
ClassFile BaseInfo = ReadPointer<ClassFile>(Ptr);
if (BaseInfo.MagicNumber == 0xBEBAFECA)
{
std::cout << "Magic Number: " << BaseInfo.MagicNumber << "\n";
std::cout << "Minor Number: " << BaseInfo.MinorVersion << "\n";
std::cout << "Major Number: " << BaseInfo.MajorVersion << "\n";
std::cout << "Const Pool Size: " << BaseInfo.ConstantPoolCount << "\n";
std::vector<ConstantPool> ConstPool;
for (int I = 0; I < BaseInfo.ConstantPoolCount - 1; ++I)
{
ConstPool.push_back(ConstantPool(Ptr));
if (ConstPool.back().type == 5 || ConstPool.back().type == 6)
++I;
}
std::cout << "Access Flags: " << ReadPointer<short>(Ptr);
}
File.close();
}
}
答案 0 :(得分:1)
一个错误是
intValue = ReadPointer<double>(Pointer);
你正在阅读一个双重而不是一个int,这会抛弃其他一切。
当然,您的代码也有很多其他问题。例如,您完全忽略了对齐和结构填充问题。