用dumpbin来查看dll导出了哪些函数(接口)。尤其是观察导出的那个类继承自模板(实例化了模板后再导出)

启动vs的“开发人员命令提示”

用dumpbin来查看dll导出了哪些函数(接口)。尤其是观察导出的那个类继承自模板(实例化了模板后再导出)_第1张图片

直接执行dumpbin,它会给出所有支持的选项:

用dumpbin来查看dll导出了哪些函数(接口)。尤其是观察导出的那个类继承自模板(实例化了模板后再导出)_第2张图片

给出dll的完整路径,可以将信息导出到文本文件:

D:\DevTools\VS2015>dumpbin /exports D:\123\test.dll >123123.txt

下面的代码

template <
    typename DerivedName, //signature,在类中不做使用。
    typename AbstractProduct, //接口
    typename ProductTypeKey, //key
    typename ...ArgTypes //其他参数
>
class GenericFactoryPro
{
protected:

    GenericFactoryPro() {}
    GenericFactoryPro(const GenericFactoryPro&) = delete; 
    GenericFactoryPro(GenericFactoryPro&&) = delete;
    GenericFactoryPro operator=(const GenericFactoryPro& other) = delete;

public:
    ~GenericFactoryPro() {}

    //具体产品注册类Register。使用内嵌类可明显简化设计
    template 
    class Register
    {
    public:
        Register(const ProductTypeKey& key)
        {
            ...
        }
    private:
        inline static AbstractProduct* ConcreteProductCreator(ArgTypes... args)
        {
            ...
        }
    };

    bool Unregister(const ProductTypeKey& conp)
    {
        ...
    }

    std::shared_ptr NewInstance(const ProductTypeKey& conp, ArgTypes... args)
    {
        ...
    }

    std::vector GetOrderedKeyVec()
    {
        ...
    }


    int GetSize()
    {
        ..
    }

    ProductTypeKey GetKey(unsigned n) 
    {
       ...
    }

    inline static GenericFactoryPro& GetSingletonInstance()
    {
        static GenericFactoryPro unique_generic_factory;
        return unique_generic_factory;
    }
};


struct EXPORT_attribute ECClassDefMgr123 : public GenericFactoryPro
{
    //ECClassDefMgr() = delete;
    //~ECClassDefMgr() = delete;
};

会看到类似这样的导出信息,

         10    9 005EDEA8 ?$TSS0@?1??GetSingletonInstance@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@SAAEAV2@XZ@4HA = ?$TSS0@?1??GetSingletonInstance@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@SAAEAV2@XZ@4HA (int `public: static class GenericFactoryPro & __cdecl GenericFactoryPro::GetSingletonInstance(void)'::`2'::$TSS0)

         18   11 00001E79 ??0?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@IEAA@XZ = @ILT+3700(??0?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@IEAA@XZ)

        304  12F 0001203A ??1?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAA@XZ = @ILT+69685(??1?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAA@XZ)

       1224  4C7 000089C7 ?GetKey@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAA?AUObjectType@@I@Z = @ILT+31170(?GetKey@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAA?AUObjectType@@I@Z)

       1262  4ED 0000CDBF ?GetOrderedKeyVec@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAA?AV?$vector@UObjectType@@V?$allocator@UObjectType@@@std@@@std@@XZ = @ILT+48570(?GetOrderedKeyVec@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAA?AV?$vector@UObjectType@@V?$allocator@UObjectType@@@std@@@std@@XZ)

       1308  51B 0000CCD9 ?GetSingletonInstance@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@SAAEAV1@XZ = @ILT+48340(?GetSingletonInstance@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@SAAEAV1@XZ)

       1316  523 000106E5 ?GetSize@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAAHXZ = @ILT+63200(?GetSize@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAAHXZ)

       1554  611 000059B6 ?NewInstance@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAA?AV?$shared_ptr@UECClassDef@@@std@@AEBUObjectType@@@Z = @ILT+18865(?NewInstance@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAA?AV?$shared_ptr@UECClassDef@@@std@@AEBUObjectType@@@Z)

       1788  6FB 00014623 ?Unregister@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAA_NAEBUObjectType@@@Z = @ILT+79390(?Unregister@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@QEAA_NAEBUObjectType@@@Z)

       2348  92B 005EDE78 ?unique_generic_factory@?1??GetSingletonInstance@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@SAAEAV2@XZ@4V2@A = ?unique_generic_factory@?1??GetSingletonInstance@?$GenericFactoryPro@UECClassDefMgr123@@UECClassDef@@UObjectType@@$$V@@SAAEAV2@XZ@4V2@A (class GenericFactoryPro `public: static class GenericFactoryPro & __cdecl GenericFactoryPro::GetSingletonInstance(void)'::`2'::unique_generic_factory)

为什么上面的GenericFactoryPro要加第一个参数呢?

首先,继承自GenericFactoryPro主要是为了生成一个单例,添加的第一个参数并没有用在实际代码中,主要是为了将导出的函数名保持唯一性。如果不唯一的话就会出现有意思的事,见:http://t.csdnimg.cn/BXdie

比如:

A.dll里这样定义:

template <
    typename AbstractProduct, //接口
    typename ProductTypeKey=std::wstring, //key
    typename ...ArgTypes //其他参数
>
class GenericFactory
{
protected:

    GenericFactory() {}
    GenericFactory(const GenericFactory&) = delete; 
    GenericFactory(GenericFactory&&) = delete;
    GenericFactory operator=(const GenericFactory& other) = delete;

public:
    ~GenericFactory() {}

    //具体产品注册类Register。使用内嵌类可明显简化设计
    template 
    class Register
    {
    public:
        Register(const ProductTypeKey& key)
        {
            GenericFactory::GetSingletonInstance().m_OrderedKeyVec.push_back(key);
            GenericFactory::GetSingletonInstance().m_mapConFactory.emplace(key, ConcreteProductCreator);
        }
    private:
        inline static AbstractProduct* ConcreteProductCreator(ArgTypes... args)
        {
            ...
        }
    };

    bool Unregister(const ProductTypeKey& conp)
    {
        ...
    }

    std::shared_ptr NewInstance(const ProductTypeKey& conp, ArgTypes... args)
    {
       ...
    }

    std::vector GetOrderedKeyVec()
    {
        ..
    }


    int GetSize()
    {
        ...
    }

    ProductTypeKey GetKey(unsigned n) 
    {
       ...
    }

    inline static GenericFactory& GetSingletonInstance()
    {
        static GenericFactory unique_generic_factory;
        return unique_generic_factory;
    }
};

struct EXPORT_attribute ECClassDefMgr123 : public GenericFactory
{
    //ECClassDefMgr() = delete;
    //~ECClassDefMgr() = delete;
};

struct EXPORT_attribute ECClassDefMgr456 : public GenericFactoryPro
{
    //ECClassDefMgr() = delete;
    //~ECClassDefMgr() = delete;
};

B.dll里这样使用

void fun()
{
    auto& fac1 = ECClassDefMgr123::GetSingletonInstance();
    auto& fac2 = ECClassDefMgr456::GetSingletonInstance();
    if(&fac1==&fac2)
    {
        std::cout<<"wc, 地址相同,它俩指向了同一个单例!";
    }
}

会发现,虽然类名不一样(一个是ECClassDefMgr123,一个是ECClassDefMgr456),但它们最后指向的单例是同一个。因为它们用的是同一个导出的static变量:unique_generic_factory

导出名称类似:

?unique_generic_factory@?1??GetSingletonInstance@?$GenericFactoryPro@@UECClassDef@@UObjectType@@$$V@@SAAEAV2@XZ@4V2@A = ?unique_generic_factory@?1??GetSingletonInstance@?$GenericFactoryPro@@UECClassDef@@UObjectType@@$$V@@SAAEAV2@XZ@4V2@A (class GenericFactoryPro `public: static class GenericFactoryPro & __cdecl GenericFactoryPro::GetSingletonInstance(void)'::`2'::unique_generic_factory)

你可能感兴趣的:(c++,开发语言)