한 줄 요약 - 해보니까 안깨는 게 나을거같다.
하지만 언제나 규칙을 위반하기 좋아하는 우리들은 일단 해보는 것이다.
저번에 시도한 것의 패인은 vptr의 타입인 void*의 해석에 문제가 있던 것이다.
void*의 해석이 1바이트인 줄 알았는데 컴파일러마다 다를 수 있다는 것이다.
gcc는 void*의 해석이 1바이트
visual c++는 void*의 해석이 0바이트인 것이다.
따라서 +8, +4 이짓 해봤자 별 의미가 없던 것.
코드로 살펴보자
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | using namespace std; #define BreakRule(x) (&x+4) class Widget { public: Widget(int init_num,char* init_str) :m_val(init_num) { int str_length = strlen(init_str) + 1; m_str = new char[str_length]; strcpy(m_str, init_str); } ~Widget() { delete[] m_str; } virtual void VirtualFunc() { cout << "I'm virtual function" << endl; } int* GetVal() { return &m_val; } char** GetStr() { return &m_str; } private: int m_val; char* m_str; }; int main(void) { Widget w(128, "ABCD"); // 이건 되지롱 printf("%d
", *(int*)((char*)&w + 4)); printf("%s
",*(char**)((char*)&w + 8)); // 천천히 살펴보자 // &w를 우선 char*로 해석한다 char*로 해석하는 이유는 // +4라는 표시가 곧 +4바이트로 해석하기 위함이다. // char는 1바이트니까 // 이것을 통하여 w인스턴스에서 총 +4바이트한 위치를 얻을 수있고 // 이 주소값을 다시 int형으로 해석하기 위해 (int*)로 캐스팅을 해준다 // 마지막으로 *을 붙여서 주소에 담긴 값을 얻어낸다. return 0; } | cs |
타입 캐스팅 떡칠(이정도를 떡칠이라 할 수 있을진 모르겠으나 내 기준에선)이 되어버린 것이다..
-끝-
아니면 char* pw로 담아주고 먼저 타입캐스팅을 해준다면 (char*)은 없앨 수도 있다.
오옹?
(int)((void **)(&w))[1], (char*)((void **)(&w))[2]
하지만 갓바는 안되죠 크킄
갓바는 리플렉션
갓무룩