আপনি উপরের নিবন্ধগুলিতে কত বিভ্রান্তিকর তথ্য পড়তে পারবেন তা অবিশ্বাস্য ...
এমনকি মাইক্রোসফ্ট এমএসডিএন ডকুমেন্টেশনে ইসব্যাডপিটিআর নিষিদ্ধ বলে দাবি করা হয়েছে। ওহ ভাল - আমি ক্র্যাশ না করে কাজের প্রয়োগ পছন্দ করি। এমনকি যদি টার্ম ওয়ার্কিং ভুলভাবে কাজ করে তবে (যতক্ষণ না শেষ ব্যবহারকারী ব্যবহারের সাথে চালিয়ে যেতে পারেন)।
গুগল করে আমি উইন্ডোজের জন্য কোনও কার্যকর উদাহরণ খুঁজে পাইনি - 32-বিট অ্যাপসের সমাধান পেয়েছি,
http://www.codeproject.com/script/Content/ViewAssociatedFile.aspx?rzp=%2FKB%2Fsystem%2Fdetect-driver%2F%2FDtetectDriverSrc.zip&zep=DedctDriverSrc%2FDteteddrc%%fdccrt%crtcrr%%fdtcrrt%crtcrc… = 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;
}
এবং নিম্নলিখিত কোডটি পয়েন্টারটি বৈধ আছে কি না তা সনাক্ত করতে পারে, আপনার সম্ভবত কিছু NUL চেকিং যুক্ত করা দরকার:
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 টি এপিআই কল করা হচ্ছে - সমালোচনামূলক অ্যাপ্লিকেশনগুলির জন্য ওভারকিল হতে পারে।
যদি কেউ সি # / পরিচালিত সি ++ কলগুলির সাথে তুলনা করে পয়েন্টার চেকিংয়ের ওভারহেড পরিমাপ করতে পারে তবে এটি ভাল good