यह अविश्वसनीय है कि आप ऊपर दिए गए लेखों में कितनी भ्रामक जानकारी पढ़ सकते हैं ...
और यहां तक कि Microsoft msdn प्रलेखन में IsBadPtr को प्रतिबंधित करने का दावा किया गया है। ओह अच्छी तरह से - मैं दुर्घटनाग्रस्त होने के बजाय काम के आवेदन को प्राथमिकता देता हूं। भले ही टर्म वर्किंग गलत तरीके से काम कर रहा हो (जब तक एंड-यूज़र एप्लिकेशन के साथ जारी रह सकता है)।
Googling द्वारा मुझे विंडोज़ के लिए कोई उपयोगी उदाहरण नहीं मिला - 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 एपीआई कॉल किए जा रहे हैं - समय के लिए महत्वपूर्ण अनुप्रयोगों के लिए ओवरकिल हो सकता है।
अच्छा होगा अगर कोई उदाहरण के लिए C # / प्रबंधित c ++ कॉल की तुलना में पॉइंटर चेकिंग के ओवरहेड को माप सके।