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

📄 rtti.cpp

📁 不错的东西 请查看 WINCE OS
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Output: pointer to the appropriate sub-object of targetted type; NULL if cast fails
//
// Side-effects: NONE.
//

static _RTTIBaseClassDescriptor * __cdecl FindSITargetTypeInstance (
                                PVOID pCompleteObject,                          // pointer to complete object
                                _RTTICompleteObjectLocator *pCOLocator, // pointer to Locator of complete object
                                _RTTITypeDescriptor *pSrcTypeID,        // pointer to TypeDescriptor of source object
                                int SrcOffset,                                          // offset of source object in complete object
                                _RTTITypeDescriptor *pTargetTypeID)     // pointer to TypeDescriptor of result of cast
{
    _RTTIBaseClassDescriptor *pBase;
    _RTTIBaseClassDescriptor * const *pBasePtr;
    DWORD i;

    for (i = 0, pBasePtr = pCOLocator->pClassDescriptor->pBaseClassArray->arrayOfBaseClassDescriptors;
         i < pCOLocator->pClassDescriptor->numBaseClasses;
         i++, pBasePtr++) {

        // Test type of selected base class
        pBase = *pBasePtr;
        if (TYPEIDS_EQ(pBase->pTypeDescriptor, pTargetTypeID) &&
            !(BCD_ATTRIBUTES(*pBase) & BCD_NOTVISIBLE)) {
            return pBase;
        }
    }
    return NULL;
}


/////////////////////////////////////////////////////////////////////////////
//
// FindMITargetTypeInstance - workhorse routine of __RTDynamicCast() in a Multiple-Inheritance hierarchy
//
// Output: pointer to the appropriate sub-object of targetted type; NULL if cast fails
//
// Side-effects: NONE.
//

static _RTTIBaseClassDescriptor * __cdecl FindMITargetTypeInstance (
                                PVOID pCompleteObject,                          // pointer to complete object
                                _RTTICompleteObjectLocator *pCOLocator, // pointer to Locator of complete object
                                _RTTITypeDescriptor *pSrcTypeID,        // pointer to TypeDescriptor of source object
                                int SrcOffset,                                          // offset of source object in complete object
                                _RTTITypeDescriptor *pTargetTypeID)     // pointer to TypeDescriptor of result of cast
{
    _RTTIBaseClassDescriptor *pBase, *pSubBase;
    _RTTIBaseClassDescriptor * const *pBasePtr, * const *pSubBasePtr;
    DWORD i, j;

                                // First, try down-casts
    for (i = 0, pBasePtr = pCOLocator->pClassDescriptor->pBaseClassArray->arrayOfBaseClassDescriptors;
         i < pCOLocator->pClassDescriptor->numBaseClasses;
         i++, pBasePtr++) {
        
        pBase = *pBasePtr;
                                // Test type of selected base class
        if (TYPEIDS_EQ(pBase->pTypeDescriptor, pTargetTypeID)) {
                                // If base class is proper type, see if it contains our instance of source class
            for (j = 0, pSubBasePtr = pBasePtr+1;
                 j < pBase->numContainedBases;
                 j++, pSubBasePtr++) {

                pSubBase = *pSubBasePtr;
                if (TYPEIDS_EQ(pSubBase->pTypeDescriptor, pSrcTypeID) &&
                    (PMDtoOffset(pCompleteObject, pSubBase->where) == SrcOffset)) {
                                // Yes, this is the proper instance of source class
                    return pBase;
                }
            }
        }
    }

                                // Down-cast failed, try cross-cast
    for (i = 0, pBasePtr = pCOLocator->pClassDescriptor->pBaseClassArray->arrayOfBaseClassDescriptors;
         i < pCOLocator->pClassDescriptor->numBaseClasses;
         i++, pBasePtr++) {

        pBase = *pBasePtr;
                                // Check if base class has proper type, is accessible & is unambiguous
        if (TYPEIDS_EQ(pBase->pTypeDescriptor, pTargetTypeID) &&
            !(BCD_ATTRIBUTES(*pBase) & BCD_NOTVISIBLE) &&
            !(BCD_ATTRIBUTES(*pBase) & BCD_AMBIGUOUS)) {
            return pBase;
        }
    }

    return NULL;
}


/////////////////////////////////////////////////////////////////////////////
//
// FindVITargetTypeInstance - workhorse routine of __RTDynamicCast() in a Virtual-Inheritance hierarchy
//
// Output: pointer to the appropriate sub-object of targetted type; NULL if cast fails
//
// Side-effects: NONE.
//

static _RTTIBaseClassDescriptor * __cdecl FindVITargetTypeInstance (
                                PVOID pCompleteObject,                          // pointer to complete object
                                _RTTICompleteObjectLocator *pCOLocator, // pointer to Locator of complete object
                                _RTTITypeDescriptor *pSrcTypeID,        // pointer to TypeDescriptor of source object
                                int SrcOffset,                                          // offset of source object in complete object
                                _RTTITypeDescriptor *pTargetTypeID)     // pointer to TypeDescriptor of result of cast
{
    _RTTIBaseClassDescriptor *pBase, *pSubBase;
    _RTTIBaseClassDescriptor * const *pBasePtr, * const *pSubBasePtr;
    _RTTIBaseClassDescriptor *pResult = NULL;
    DWORD i, j;

                                // First, try down-casts
    for (i = 0, pBasePtr = pCOLocator->pClassDescriptor->pBaseClassArray->arrayOfBaseClassDescriptors;
         i < pCOLocator->pClassDescriptor->numBaseClasses;
         i++, pBasePtr++) {
        
        pBase = *pBasePtr;
                                // Test type of selected base class
        if (TYPEIDS_EQ(pBase->pTypeDescriptor, pTargetTypeID)) {
                                // If base class is proper type, see if it contains our instance of source class
            for (j = 0, pSubBasePtr = pBasePtr+1;
                 j < pBase->numContainedBases;
                 j++, pSubBasePtr++) {

                pSubBase = *pSubBasePtr;
                if (TYPEIDS_EQ(pSubBase->pTypeDescriptor, pSrcTypeID) &&
                    (PMDtoOffset(pCompleteObject, pSubBase->where) == SrcOffset)) {
                                // Yes, this is the proper instance of source class - make sure it is unambiguous
                                // Ambiguity now determined by inequality of offsets of source class within complete object, not pointer inequality
                    if ((pResult != NULL) && (PMDtoOffset(pCompleteObject, pResult->where) != PMDtoOffset(pCompleteObject, pBase->where))) {
                                // We already found an earlier instance, hence ambiguity
                        return NULL;
                    }
                    else {
                                // Unambiguous
                        pResult = pBase;
                    }
                }
            }
        }
    }

    if (pResult != NULL)
        return pResult;

                                // Down-cast failed, try cross-cast
    for (i = 0, pBasePtr = pCOLocator->pClassDescriptor->pBaseClassArray->arrayOfBaseClassDescriptors;
         i < pCOLocator->pClassDescriptor->numBaseClasses;
         i++, pBasePtr++) {

        pBase = *pBasePtr;
                                // Check if base class has proper type, is accessible & is unambiguous
        if (TYPEIDS_EQ(pBase->pTypeDescriptor, pTargetTypeID) &&
            !(BCD_ATTRIBUTES(*pBase) & BCD_NOTVISIBLE) &&
            !(BCD_ATTRIBUTES(*pBase) & BCD_AMBIGUOUS)) {
            return pBase;

        }
    }

    return NULL;
}

/////////////////////////////////////////////////////////////////////////////
//
// PMDtoOffset - Calculate member offset from PMD & this
//
// Output: The offset of the base within the complete object.
//
// Side-effects: NONE.
//


static ptrdiff_t __cdecl PMDtoOffset(
                                PVOID pThis,                    // ptr to complete object
                                const PMD& pmd)                 // pointer-to-member-data structure
{
    ptrdiff_t RetOff = 0;

    if (pmd.pdisp >= 0) {                       // if base is in the virtual part of class
        RetOff = pmd.pdisp;
        RetOff += *(ptrdiff_t*)((char*)*(ptrdiff_t*)((char*)pThis + RetOff) + pmd.vdisp);
    }

    RetOff += pmd.mdisp;

    return RetOff;
}

⌨️ 快捷键说明

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