위의 기사에서 얼마나 많은 오해의 소지가있는 정보를 읽을 수 있는지 믿을 수 없습니다.
그리고 Microsoft msdn 문서에서도 IsBadPtr은 금지되었다고 주장됩니다. 오 글쎄-나는 충돌보다는 작동하는 응용 프로그램을 선호합니다. 용어 작업이 잘못 작동하더라도 (최종 사용자가 응용 프로그램을 계속할 수있는 한).
인터넷 검색을 통해 Windows에 대한 유용한 예를 찾지 못했습니다. 32 비트 앱에 대한 솔루션을 찾았습니다.
http://www.codeproject.com/script/Content/ViewAssociatedFile.aspx?rzp=%2FKB%2Fsystem%2Fdetect-driver%2F%2FDetectDriverSrc.zip&zep=DetectDriverSrc%2FDetectDriver%2Fsrc%2FdrvCppLib%2Frtti.cpp&obid=58895&obtid=2&ovid = 2
하지만 64 비트 앱도 지원해야하므로이 솔루션이 작동하지 않았습니다.
하지만 와인의 소스 코드를 모아서 64 비트 앱에서도 작동하는 비슷한 종류의 코드를 만들었습니다. 여기에 코드를 첨부하세요.
#include <typeinfo.h>
typedef void (*v_table_ptr)();
typedef struct _cpp_object
{
v_table_ptr* vtable;
} cpp_object;
#ifndef _WIN64
typedef struct _rtti_object_locator
{
unsigned int signature;
int base_class_offset;
unsigned int flags;
const type_info *type_descriptor;
} rtti_object_locator;
#else
typedef struct
{
unsigned int signature;
int base_class_offset;
unsigned int flags;
unsigned int type_descriptor;
unsigned int type_hierarchy;
unsigned int object_locator;
} rtti_object_locator;
#endif
static const rtti_object_locator* RTTI_GetObjectLocator(void* inptr)
{
cpp_object* cppobj = (cpp_object*) inptr;
const rtti_object_locator* obj_locator = 0;
if (!IsBadReadPtr(cppobj, sizeof(void*)) &&
!IsBadReadPtr(cppobj->vtable - 1, sizeof(void*)) &&
!IsBadReadPtr((void*)cppobj->vtable[-1], sizeof(rtti_object_locator)))
{
obj_locator = (rtti_object_locator*) cppobj->vtable[-1];
}
return obj_locator;
}
그리고 다음 코드는 포인터가 유효한지 여부를 감지 할 수 있으므로 NULL 검사를 추가해야합니다.
CTest* t = new CTest();
const rtti_object_locator* ptr = RTTI_GetObjectLocator(t);
#ifdef _WIN64
char *base = ptr->signature == 0 ? (char*)RtlPcToFileHeader((void*)ptr, (void**)&base) : (char*)ptr - ptr->object_locator;
const type_info *td = (const type_info*)(base + ptr->type_descriptor);
#else
const type_info *td = ptr->type_descriptor;
#endif
const char* n =td->name();
이것은 포인터에서 클래스 이름을 가져옵니다-귀하의 요구에 충분해야한다고 생각합니다.
내가 여전히 두려워하는 한 가지는 포인터 검사의 성능입니다. 위의 코드 스 니펫에는 이미 3-4 개의 API 호출이 수행되고 있습니다. 시간이 중요한 애플리케이션에서는 과도 할 수 있습니다.
예를 들어 C # / 관리되는 C ++ 호출과 비교하여 누군가가 포인터 검사의 오버 헤드를 측정 할 수 있다면 좋을 것입니다.