ไม่น่าเชื่อว่าคุณสามารถอ่านข้อมูลที่ทำให้เข้าใจผิดได้มากแค่ไหนในบทความด้านบน ...
และแม้แต่ในเอกสาร Microsoft msdn IsBadPtr ก็อ้างว่าถูกแบน โอ้ดี - ฉันชอบแอปพลิเคชันที่ใช้งานได้มากกว่าการขัดข้อง แม้ว่าการทำงานในระยะอาจทำงานผิดพลาด (ตราบใดที่ผู้ใช้ปลายทางสามารถดำเนินการต่อกับแอปพลิเคชันได้)
โดย googling ฉันไม่พบตัวอย่างที่มีประโยชน์สำหรับ windows - พบวิธีแก้ปัญหาสำหรับแอพ 32 บิต
http://www.codeproject.com/script/Content/ViewAssociatedFile.aspx? = 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();
สิ่งนี้ได้รับชื่อคลาสจากตัวชี้ - ฉันคิดว่ามันน่าจะเพียงพอสำหรับความต้องการของคุณ
สิ่งหนึ่งที่ฉันยังคงกลัวคือประสิทธิภาพของการตรวจสอบตัวชี้ - ในโค้ดโค้ดด้านบนมีการเรียก API 3-4 ครั้งแล้ว - อาจใช้งานมากเกินไปสำหรับแอปพลิเคชันที่มีความสำคัญต่อเวลา
จะเป็นการดีถ้ามีคนสามารถวัดค่าเหนือศีรษะของการตรวจสอบตัวชี้เทียบกับการเรียก C # / c ++ ที่มีการจัดการ