To me, a vector layout looks something like this:
struct MyViewOnHowVectorLooksLike
{
public:
int* _first, * _last, * _end;
};
Known Parameters:
- Address of the
std::vector<Type>
object - size of the
<Type>
Questions:
- Find the address of the first element and the last element in the vector
Is there any way to access the first and last elements in a std::vector
by its base memory address, which is &Test
in the above test case, not by calling any build-in method of the std::vector
function eg [0]
, .front()
, etc; (The reason why I'm doing this is to have a static reflection system which could output the content of any given written vector type)
struct FTestData {
int data;
};
class TestClass {
public:
// test array
std::vector<FTestData> testArray;
TestClass(){}
};
// TEST CASE
FTestData testCon1 = FTestData();
testCon1.data = 111;
FTestData testCon2 = FTestData();
testCon2.data = 222;
TestClass Test = TestClass();
Test.testArray.push_back(testCon1);
Test.testArray.push_back(testCon2);
std::vector<FTestData>* TestData = (std::vector<FTestData>*)((size_t)&Test);
size_t ptr = (size_t)TestData;
FTestData& TestElement1 = (*TestData)[0];
size_t realFirstElementAddress = (size_t)&TestElement1;
// try to get the address of the first element in the vector but it gives me the wrong address
size_t CustomFirstElementAddress = (*(size_t*)(ptr));
// expecting those two to be the same but it wasnt
assert(realFirstElementAddress == CustomFirstElementAddress);
I thought the _First
and _Last
are right next to the base address, but it keeps outputting the wrong results.
AddOn: The real problem I am trying to solve is to have a detail panel with my own reflection system, which could allow me do something like this. It works for most common types, and nested class.
{
if (field.Type == "int") {
int location[1];
auto& value = *(int*)((size_t)&Component + Offset + field.Offset);
memcpy(location, &value, sizeof(location));
if (ImGui::DragInt(fieldName.c_str(), location, 0.1f, 0.0f, 0.0f, "%.1f"))
{
memcpy(&value, location, sizeof(location));
}
}
else if (field.Type == "std::string") {
char buffer[256];
memset(buffer, 0, sizeof(buffer));
auto& value = *(std::string*)((size_t)&Component+ Offset + field.Offset);
strcpy(buffer, value.c_str());
if (ImGui::InputText(fieldName.c_str(), buffer, sizeof(buffer))) {
value = std::string(buffer);
}
}
else if (field.Type == "bool") {
bool location[1];
auto& value = *(bool*)((size_t)&Component + Offset + field.Offset);
memcpy(location, &value, sizeof(location));
if (ImGui::Checkbox(fieldName.c_str(), location)) {
memcpy(&value, location, sizeof(location));
}
}
else if (field.Type == "float") {
float location[1];
auto& value = *(float*)((size_t)&Component + Offset + field.Offset);
memcpy(location, &value, sizeof(location));
if (ImGui::DragFloat(fieldName.c_str(), location, 0.1f, 0.0f, 0.0f, "%.1f"))
{
memcpy(&value, location, sizeof(location));
}
}
}
Aucun commentaire:
Enregistrer un commentaire