启动vs的“开发人员命令提示”
直接执行dumpbin,它会给出所有支持的选项:
给出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
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
为什么上面的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