⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtti.cpp

📁 不错的东西 请查看 WINCE OS
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/***
*rtti.cpp - C++ runtime type information
*
*
*Purpose:
*       Implementation of C++ standard runtime type information
*
****/

extern "C" {
#include <windows.h>
};

#include <stdio.h>
#include <typeinfo>
#include <rtti.h>

static PVOID __cdecl FindCompleteObject(PVOID *);
static _RTTIBaseClassDescriptor * __cdecl FindSITargetTypeInstance(PVOID,_RTTICompleteObjectLocator *,_RTTITypeDescriptor *,int,_RTTITypeDescriptor *);
static _RTTIBaseClassDescriptor * __cdecl FindMITargetTypeInstance(PVOID,_RTTICompleteObjectLocator *,_RTTITypeDescriptor *,int,_RTTITypeDescriptor *);
static _RTTIBaseClassDescriptor * __cdecl FindVITargetTypeInstance(PVOID,_RTTICompleteObjectLocator *,_RTTITypeDescriptor *,int,_RTTITypeDescriptor *);
static ptrdiff_t __cdecl PMDtoOffset(PVOID, const PMD&);


/////////////////////////////////////////////////////////////////////////////
//
// __RTCastToVoid - Implements dynamic_cast<void*>
//
// Output: Pointer to complete object containing *inptr
//
// Side-effects: NONE.
//

extern "C" PVOID __cdecl __RTCastToVoid (PVOID inptr)                   // Pointer to polymorphic object
{

    if (inptr == NULL)
        return NULL;

    __try {
        return FindCompleteObject((PVOID *)inptr);
    }
    __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER: EXCEPTION_CONTINUE_SEARCH) {
        throw std::__non_rtti_object ("Access violation - no RTTI data!");
    }
}


/////////////////////////////////////////////////////////////////////////////
//
// __RTtypeid - Implements typeid() operator
//
// Output: Pointer to type descriptor of complete object containing *inptr
//
// Side-effects: NONE.
//

extern "C" PVOID __cdecl __RTtypeid (PVOID inptr)               // Pointer to polymorphic object
{

    if (!inptr) {
        throw std::bad_typeid ("Attempted a typeid of NULL pointer!");          // WP 5.2.7
        return NULL;
    }

    __try {
        // Ptr to CompleteObjectLocator should be stored at vfptr[-1]
        _RTTICompleteObjectLocator *pCompleteLocator = (_RTTICompleteObjectLocator *) ((*((void***)inptr))[-1]);

#if 0
        if (!IsBadReadPtr((const void *)pCompleteLocator->pTypeDescriptor, sizeof(TypeDescriptor))) {
            return (PVOID) pCompleteLocator->pTypeDescriptor;
        }
        else {
            throw std::__non_rtti_object ("Bad read pointer - no RTTI data!");
            return NULL;
        }
#else
        return (PVOID) pCompleteLocator->pTypeDescriptor;
#endif
    }
    __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER: EXCEPTION_CONTINUE_SEARCH) {
        throw std::__non_rtti_object ("Access violation - no RTTI data!");
    }
}


/////////////////////////////////////////////////////////////////////////////
//
// __RTDynamicCast - Runtime implementation of dynamic_cast<> operator
//
// Output: Pointer to the appropriate sub-object, if possible; NULL otherwise
//
// Side-effects: Throws bad_cast() if cast fails & input of dynamic_cast<> is a reference
//

extern "C" PVOID __cdecl __RTDynamicCast (
                                        PVOID inptr,                                    // Pointer to polymorphic object
                                        LONG VfDelta,                                   // Offset of vfptr in object
                                        PVOID SrcType,                                  // Static type of object pointed to by inptr
                                        PVOID TargetType,                               // Desired result of cast
                                        BOOL isReference)                               // TRUE if input is reference, FALSE if input is ptr
{
    PVOID pResult;
    _RTTIBaseClassDescriptor *pBaseClass;

    if (inptr == NULL)
        return NULL;

    __try {
        PVOID pCompleteObject = FindCompleteObject((PVOID *)inptr);
        _RTTICompleteObjectLocator *pCompleteLocator = (_RTTICompleteObjectLocator *) ((*((void***)inptr))[-1]);

        // Adjust by vfptr displacement, if any
        inptr = (PVOID *) ((char *)inptr - VfDelta);
        // Calculate offset of source object in complete object
        int inptr_delta = (char *)inptr - (char *)pCompleteObject;

        if (!(CHD_ATTRIBUTES(*COL_PCHD(*pCompleteLocator)) & CHD_MULTINH)) {             // if not multiple inheritance
            pBaseClass = FindSITargetTypeInstance(pCompleteObject,
                                                  pCompleteLocator,
                                                  (_RTTITypeDescriptor *) SrcType,
                                                  inptr_delta,
                                                  (_RTTITypeDescriptor *) TargetType);
        } else if (!(CHD_ATTRIBUTES(*COL_PCHD(*pCompleteLocator)) & CHD_VIRTINH)) { // if multiple, but not virtual, inheritance
            pBaseClass = FindMITargetTypeInstance(pCompleteObject,
                                                  pCompleteLocator,
                                                  (_RTTITypeDescriptor *) SrcType,
                                                  inptr_delta,
                                                  (_RTTITypeDescriptor *) TargetType);
        } else {                                                                   // if virtual inheritance
            pBaseClass = FindVITargetTypeInstance(pCompleteObject,
                                                  pCompleteLocator,
                                                  (_RTTITypeDescriptor *) SrcType,
                                                  inptr_delta,
                                                  (_RTTITypeDescriptor *) TargetType);
        }

        if (pBaseClass != NULL) {
            // Calculate ptr to result base class from pBaseClass->where
            pResult = ((char *) pCompleteObject) + PMDtoOffset(pCompleteObject, pBaseClass->where);
        }else {
            pResult = NULL;
            if (isReference) {
                throw std::bad_cast("Bad dynamic_cast!");
            }
        }

    }
    __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER: EXCEPTION_CONTINUE_SEARCH) {
        pResult = NULL;
        throw std::__non_rtti_object ("Access violation - no RTTI data!");
    }

    return pResult;
        
}

/////////////////////////////////////////////////////////////////////////////
//
// FindCompleteObject - Calculate member offset from PMD & this
//
// Output: pointer to the complete object containing class *inptr
//
// Side-effects: NONE.
//

static PVOID __cdecl FindCompleteObject (PVOID *inptr)          // Pointer to polymorphic object
{
    // Ptr to CompleteObjectLocator should be stored at vfptr[-1]
    _RTTICompleteObjectLocator *pCompleteLocator = (_RTTICompleteObjectLocator *) ((*((void***)inptr))[-1]);
    char *pCompleteObject = (char *)inptr - pCompleteLocator->offset;
    // Adjust by construction displacement, if any
    if (pCompleteLocator->cdOffset)
        pCompleteObject += *(ptrdiff_t *)((char *)inptr - pCompleteLocator->cdOffset);
    return (PVOID) pCompleteObject;
}


/////////////////////////////////////////////////////////////////////////////
//
// FindSITargetTypeInstance - workhorse routine of __RTDynamicCast() in a Single-Inheritance hierarchy
//

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -