首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过代码在typelib文件中查找依赖类型库

通过代码在typelib文件中查找依赖类型库
EN

Stack Overflow用户
提问于 2017-07-13 00:22:52
回答 1查看 332关注 0票数 2

寻找查找类型库的依赖类型库的方法。例如,在IDL中声明依赖库时,公共依赖项是stdore2.tlb,并声明为:

importlib(“stdoe2.tlb”);

我可以使用OleView.exe查看这些依赖项,但我正在尝试如何在代码中做到这一点。在ITypeLib或ITypeLib2接口中似乎没有任何成员可以获取这些依赖项。我已经搜索了OLE自动化参考,但还没有找到获取接口的方法。

它们是否以类型库的二进制资源格式存在?

有谁能给我指个方向吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-14 05:04:43

下面是类型库的GetDependencies函数的完整实现。

这将返回ITypeLibPtr智能指针的unordered_set。请注意散列函数,它允许在unordered_set和其他散列容器中使用这些智能指针。

这只返回第一级依赖项。如果这些类型库具有其他依赖项,则可以以某种递归方式使用此方法来获取完整的依赖项集(第一级及更高级别)。

循环引用(例如,IInterfaceA有一个返回IInterfaceB指针的属性,IInterfaceB有一个返回IInterfaceA指针的属性)是通过在类型库中爬行时存储被访问的ITypeInfounordered_set来支持的。

此代码旨在抛出_com_error异常(除了使用unordered_set时可能发生的任何STL异常)。适当地处理这些问题。如果您不想处理_com_error异常,请将_com_util::CheckError调用替换为您自己的HRESULT值错误处理逻辑。

代码语言:javascript
复制
#include <windows.h>
#include <comdef.h>
#include <unordered_set>

// gets dependencies of a type library
std::unordered_set<ITypeLibPtr> GetDependencies(ITypeLib* pTypeLib);

// gathers dependencies of a type library
void GetDependenciesHelper(ITypeLib* pTypeLib, std::unordered_set<ITypeInfoPtr>* pHistory, std::unordered_set<ITypeLibPtr>* pOutput);

// gathers dependencies of a type
void GetDependenciesHelper(ITypeLib* pTypeLib, ITypeInfo* pTypeInfo, std::unordered_set<ITypeInfoPtr>* pHistory, std::unordered_set<ITypeLibPtr>* pOutput);

// gathers dependencies of a reference
void GetDependenciesHelper(ITypeLib* pTypeLib, ITypeInfo* pTypeInfo, HREFTYPE hRefType, std::unordered_set<ITypeInfoPtr>* pHistory, std::unordered_set<ITypeLibPtr>* pOutput);

// gathers dependencies of a reference
void GetDependenciesHelper(ITypeLib* pTypeLib, ITypeInfo* pTypeInfo, TYPEDESC& referencedTypeDescription, std::unordered_set<ITypeInfoPtr>* pHistory, std::unordered_set<ITypeLibPtr>* pOutput);

// gathers dependencies of a function declaration
void GetDependenciesHelper(ITypeLib* pTypeLib, ITypeInfo* pTypeInfo, FUNCDESC& functionDescription, std::unordered_set<ITypeInfoPtr>* pHistory, std::unordered_set<ITypeLibPtr>* pOutput);

// gathers dependencies of a variable declaration
void GetDependenciesHelper(ITypeLib* pTypeLib, ITypeInfo* pTypeInfo, VARDESC& variableDescription, std::unordered_set<ITypeInfoPtr>* pHistory, std::unordered_set<ITypeLibPtr>* pOutput);

// gathers dependencies of an array declaration
void GetDependenciesHelper(ITypeLib* pTypeLib, ITypeInfo* pTypeInfo, ARRAYDESC& arrayDescription, std::unordered_set<ITypeInfoPtr>* pHistory, std::unordered_set<ITypeLibPtr>* pOutput);

// gathers dependencies of an array element declaration
void GetDependenciesHelper(ITypeLib* pTypeLib, ITypeInfo* pTypeInfo, ELEMDESC& elementDescription, std::unordered_set<ITypeInfoPtr>* pHistory, std::unordered_set<ITypeLibPtr>* pOutput);

namespace std
{
    // provides a function for hashing ITypeLibPtr instances by their raw address
    template<> struct hash<ITypeLibPtr>
    {
        size_t operator()(ITypeLibPtr const& pTypeLib) const { return pTypeLib; }
    };
    // provides a function for hashing ITypeInfo instances by their raw address
    template<> struct hash<ITypeInfoPtr>
    {
        size_t operator()(ITypeInfoPtr const& pTypeInfo) const { return pTypeInfo; }
    };
}

std::unordered_set<ITypeLibPtr> GetDependencies(ITypeLib* pTypeLib)
{
    // get dependencies
    std::unordered_set<ITypeLibPtr> output;
    std::unordered_set<ITypeInfoPtr> history;
    GetDependenciesHelper(pTypeLib, &history, &output);
    return output;
}

void GetDependenciesHelper(ITypeLib* pTypeLib, std::unordered_set<ITypeInfoPtr>* pHistory, std::unordered_set<ITypeLibPtr>* pOutput)
{
    // iterate over type infos
    auto typeInfoCount = pTypeLib->GetTypeInfoCount();
    for (UINT typeInfoIndex = 0; typeInfoIndex < typeInfoCount; ++typeInfoIndex)
    {
        // get type info
        ITypeInfoPtr pTypeInfo;
        _com_util::CheckError(pTypeLib->GetTypeInfo(typeInfoIndex, &pTypeInfo));

        // get dependencies for type info
        GetDependenciesHelper(pTypeLib, pTypeInfo, pHistory, pOutput);
    }
}

void GetDependenciesHelper(ITypeLib* pTypeLib, ITypeInfo* pTypeInfo, std::unordered_set<ITypeInfoPtr>* pHistory, std::unordered_set<ITypeLibPtr>* pOutput)
{
    // short-circuit if we've already processed this type info
    if (!pHistory->insert(pTypeInfo).second)
        return;

    // get type attributes
    TYPEATTR* typeAttributes;
    _com_util::CheckError(pTypeInfo->GetTypeAttr(&typeAttributes));
    try
    {
        // special handling for aliases
        if (typeAttributes->typekind == TKIND_ALIAS)
        {
            // get dependencies of the alias
            GetDependenciesHelper(pTypeLib, pTypeInfo, typeAttributes->tdescAlias, pHistory, pOutput);
        }
        else
        {
            // iterate over implemented types
            auto implementedTypeCount = typeAttributes->cImplTypes;
            for (WORD implementedTypeIndex = 0; implementedTypeIndex < implementedTypeCount; ++implementedTypeIndex)
            {
                // get type reference
                HREFTYPE hRefType;
                _com_util::CheckError(pTypeInfo->GetRefTypeOfImplType(implementedTypeIndex, &hRefType));

                // get dependencies of the implementation
                GetDependenciesHelper(pTypeLib, pTypeInfo, hRefType, pHistory, pOutput);
            }

            // iterate over functions
            auto functionCount = typeAttributes->cFuncs;
            for (WORD functionIndex = 0; functionIndex < functionCount; ++functionIndex)
            {
                // get function description
                FUNCDESC* functionDescription;
                _com_util::CheckError(pTypeInfo->GetFuncDesc(functionIndex, &functionDescription));
                try
                {
                    // get dependencies of the function declaration
                    GetDependenciesHelper(pTypeLib, pTypeInfo, *functionDescription, pHistory, pOutput);
                }
                catch (...)
                {
                    // release function description
                    pTypeInfo->ReleaseFuncDesc(functionDescription);
                    throw;
                }

                // release function description
                pTypeInfo->ReleaseFuncDesc(functionDescription);
            }

            // iterate over variables
            auto variableCount = typeAttributes->cVars;
            for (WORD variableIndex = 0; variableIndex < variableCount; ++variableIndex)
            {
                // get variable description
                VARDESC* variableDescription;
                _com_util::CheckError(pTypeInfo->GetVarDesc(variableIndex, &variableDescription));
                try
                {
                    // get dependencies of the variable declaration
                    GetDependenciesHelper(pTypeLib, pTypeInfo, *variableDescription, pHistory, pOutput);
                }
                catch (...)
                {
                    // release variable description
                    pTypeInfo->ReleaseVarDesc(variableDescription);
                    throw;
                }

                // release variable description
                pTypeInfo->ReleaseVarDesc(variableDescription);
            }
        }
    }
    catch (...)
    {
        // release type attributes
        pTypeInfo->ReleaseTypeAttr(typeAttributes);
        throw;
    }

    // release type attributes
    pTypeInfo->ReleaseTypeAttr(typeAttributes);
}

void GetDependenciesHelper(ITypeLib* pTypeLib, ITypeInfo* pTypeInfo, HREFTYPE hRefType, std::unordered_set<ITypeInfoPtr>* pHistory, std::unordered_set<ITypeLibPtr>* pOutput)
{
    // get referenced type info
    ITypeInfoPtr referencedTypeInfo;
    _com_util::CheckError(pTypeInfo->GetRefTypeInfo(hRefType, &referencedTypeInfo));

    // get referenced type lib
    ITypeLibPtr referencedTypeLibrary;
    UINT referencedTypeInfoIndex;
    _com_util::CheckError(referencedTypeInfo->GetContainingTypeLib(&referencedTypeLibrary, &referencedTypeInfoIndex));

    // store dependency
    if (referencedTypeLibrary != pTypeLib)
        pOutput->insert(referencedTypeLibrary);
}

void GetDependenciesHelper(ITypeLib* pTypeLib, ITypeInfo* pTypeInfo, TYPEDESC& referencedTypeDescription, std::unordered_set<ITypeInfoPtr>* pHistory, std::unordered_set<ITypeLibPtr>* pOutput)
{
    switch (referencedTypeDescription.vt)
    {
        case VT_PTR:
        {
            // get dependencies of the pointer declaration
            GetDependenciesHelper(pTypeLib, pTypeInfo, *referencedTypeDescription.lptdesc, pHistory, pOutput);
            break;
        }
        case VT_CARRAY:
        {
            // get dependencies of the array declaration
            GetDependenciesHelper(pTypeLib, pTypeInfo, *referencedTypeDescription.lpadesc, pHistory, pOutput);
            break;
        }
        case VT_USERDEFINED:
        {
            // get dependencies of the UDT reference
            GetDependenciesHelper(pTypeLib, pTypeInfo, referencedTypeDescription.hreftype, pHistory, pOutput);
            break;
        }
    }
}

void GetDependenciesHelper(ITypeLib* pTypeLib, ITypeInfo* pTypeInfo, FUNCDESC& functionDescription, std::unordered_set<ITypeInfoPtr>* pHistory, std::unordered_set<ITypeLibPtr>* pOutput)
{
    // get dependencies of the function return value
    GetDependenciesHelper(pTypeLib, pTypeInfo, functionDescription.elemdescFunc, pHistory, pOutput);

    // iterate over parameters
    auto parameterCount = functionDescription.cParams;
    for (SHORT parameterIndex = 0; parameterIndex < parameterCount; ++parameterIndex)
    {
        // get parameter description
        auto& parameterDescription = functionDescription.lprgelemdescParam[parameterIndex];

        // get dependencies of the parameter declaration
        GetDependenciesHelper(pTypeLib, pTypeInfo, parameterDescription, pHistory, pOutput);
    }
}

void GetDependenciesHelper(ITypeLib* pTypeLib, ITypeInfo* pTypeInfo, VARDESC& variableDescription, std::unordered_set<ITypeInfoPtr>* pHistory, std::unordered_set<ITypeLibPtr>* pOutput)
{
    // get dependencies of the variable declaration
    GetDependenciesHelper(pTypeLib, pTypeInfo, variableDescription.elemdescVar, pHistory, pOutput);
}

void GetDependenciesHelper(ITypeLib* pTypeLib, ITypeInfo* pTypeInfo, ARRAYDESC& arrayDescription, std::unordered_set<ITypeInfoPtr>* pHistory, std::unordered_set<ITypeLibPtr>* pOutput)
{
    // get dependencies of the array declaration
    GetDependenciesHelper(pTypeLib, pTypeInfo, arrayDescription.tdescElem, pHistory, pOutput);
}

void GetDependenciesHelper(ITypeLib* pTypeLib, ITypeInfo* pTypeInfo, ELEMDESC& elementDescription, std::unordered_set<ITypeInfoPtr>* pHistory, std::unordered_set<ITypeLibPtr>* pOutput)
{
    // get dependencies of the array element declaration
    GetDependenciesHelper(pTypeLib, pTypeInfo, elementDescription.tdesc, pHistory, pOutput);
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45063037

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档