COMDLL
2016-04-15 13:41
405 查看
前言
不利用向导,在一个Win32普通DLL的基础上,生成一个COMDLL.COMDLL和普通DLL的区别 : 导出了4个特定的函数. 用于COMDLL的注册和反注册,得到工厂类,有了这4个导出函数,就是COMDLL.
COMDLL将注册信息放到注册表中了,宿主程序可以用COMAPI或者自己用WIN32API从注册表中读取COMDLL的全路径名称,然后调用DLL中的方法.
COMDLL中没有导出类,所以先要用导出函数DllGetObject,得到接口类的工厂类, 再用工厂类产生接口实现类的实例指针, 再去执行接口类的方法.
COM接口为了实现2进制兼容,返回的都是HRESULT, 参数用的都是每种编译器都能解释的数据类型.
每个接口类都要有IID(接口ID)
每个接口实现类都要有CLSID(类ID)和IDL(接口描述语言或等价的注册表存储信息描述)
工程下载点
srcMyComDll_2016_0415.zip效果图
工程预览
COMDLL
EXPORTS DllCanUnloadNow PRIVATE DllGetClassObject PRIVATE DllRegisterServer PRIVATE DllUnregisterServer PRIVATE
// ComClassInfo.h: interface for the CComClassInfo class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_COMCLASSINFO_H__D61F8D15_8BE1_4E07_A776_743E7CB4D94C__INCLUDED_) #define AFX_COMCLASSINFO_H__D61F8D15_8BE1_4E07_A776_743E7CB4D94C__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "guiddef.h" #include "IComClassFactory.h" typedef IComClassFactory* (PFN_MakerComClassFactory)(); class CComClassInfo { public: CComClassInfo(); CComClassInfo(GUID guid, PFN_MakerComClassFactory* pfn) { m_guid = guid; m_pfn = pfn; } virtual ~CComClassInfo(); public: GUID m_guid; PFN_MakerComClassFactory* m_pfn; }; #endif // !defined(AFX_COMCLASSINFO_H__D61F8D15_8BE1_4E07_A776_743E7CB4D94C__INCLUDED_)
// FactoryMaker.h: interface for the CFactoryMaker class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_FACTORYMAKER_H__F75F7937_15B8_4712_AB7A_1B797B31B70B__INCLUDED_) #define AFX_FACTORYMAKER_H__F75F7937_15B8_4712_AB7A_1B797B31B70B__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include <deque> #include <guiddef.h> #include "IComClassFactory.h" #include "ComClassInfo.h" class CFactoryMaker { public: CFactoryMaker(); virtual ~CFactoryMaker(); IComClassFactory* gen(REFCLSID rclsid); std::deque<CComClassInfo> m_deqInfo; }; #endif // !defined(AFX_FACTORYMAKER_H__F75F7937_15B8_4712_AB7A_1B797B31B70B__INCLUDED_)
// Helper.h: interface for the CHelpr class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_HELPER_H__4D493524_002F_4075_A6DC_46A92584A4FF__INCLUDED_) #define AFX_HELPER_H__4D493524_002F_4075_A6DC_46A92584A4FF__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 STDAPI DllRegisterServer_RegTbl(const char** szRegTable, int iAryCnt); STDAPI DllUnRegisterServer_RegTbl(const char** szRegTable, int iAryCnt); #endif // !defined(AFX_HELPER_H__4D493524_002F_4075_A6DC_46A92584A4FF__INCLUDED_)
// IComClassFactory.h: interface for the IComClassFactory class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_ICOMCLASSFACTORY_H__E3F58356_153F_4104_AE3C_F3F194F282D5__INCLUDED_) #define AFX_ICOMCLASSFACTORY_H__E3F58356_153F_4104_AE3C_F3F194F282D5__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "IComUnknown.h" struct IComClassFactory : public IComUnknown { /// @fn CreateInstance /// @brief 建立接口类实例 /// @param REFIID riid, Reference to the identifier of the interface /// @param void ** ppvObject, Address of output variable that receives the /// interface pointer requested in riid virtual HRESULT WINAPI CreateInstance(REFIID riid, void ** ppvObject) = 0; }; // {36A26845-896A-41E7-961F-C4C6B23B6262} static const GUID IID_IComClassFactory = { 0x36a26845, 0x896a, 0x41e7, { 0x96, 0x1f, 0xc4, 0xc6, 0xb2, 0x3b, 0x62, 0x62 } }; #endif // !defined(AFX_ICOMCLASSFACTORY_H__E3F58356_153F_4104_AE3C_F3F194F282D5__INCLUDED_)
// IComUnknown.h: interface for the IComMyUnknown class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_ICOMUNKNOWN_H__D3B32A06_232B_440D_885E_D808D2716BB0__INCLUDED_) #define AFX_ICOMUNKNOWN_H__D3B32A06_232B_440D_885E_D808D2716BB0__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 struct IComUnknown { /// @fn QueryInterface /// @brief 查询接口 /// @param REFIID iid, Identifier of the requested interface /// @param void ** ppvObject, Address of output variable that receives /// the interface pointer requested in iid /// @return S_OK if the interface is supported, E_NOINTERFACE if not. virtual HRESULT WINAPI QueryInterface(REFIID iid, void ** ppvObject) = 0; /// @fn AddRef /// @brief 增加引用计数 It should be called for /// every new copy of a pointer to an interface on a given object /// @param long* pRefCnt, 出参, 返回增加后的引用计数值 /// @return S_OK if the interface is supported, E_NOINTERFACE if not. virtual HRESULT WINAPI AddRef(long* pRefCnt) = 0; /// @fn Release /// @brief 减少引用计数, If the reference count on the object falls to 0, /// the object is freed from memory /// @param long* pRefCnt, 出参, 返回减小后的引用计数值 /// @return S_OK if the interface is supported, E_NOINTERFACE if not. virtual HRESULT WINAPI Release(long* pRefCnt) = 0; }; /// 每一个接口类有一个IID // {1120E240-553F-49E8-B175-536ACB8EADD8} static const GUID IID_IComUnknown = { 0x1120e240, 0x553f, 0x49e8, { 0xb1, 0x75, 0x53, 0x6a, 0xcb, 0x8e, 0xad, 0xd8 } }; #endif // !defined(AFX_ICOMUNKNOWN_H__D3B32A06_232B_440D_885E_D808D2716BB0__INCLUDED_)
// IFastString.h: interface for the IFastString class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_IFASTSTRING_H__DD942C83_85A9_4168_BC80_8B64F8E8D032__INCLUDED_) #define AFX_IFASTSTRING_H__DD942C83_85A9_4168_BC80_8B64F8E8D032__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "IComUnknown.h" struct IFastString : public IComUnknown { /// 设置源串到接口类 virtual HRESULT WINAPI set(char* pszSrc) = 0; /// 得到设置进接口类的源串 virtual HRESULT WINAPI get(char** ppszSrc) = 0; /// 得到设置的串长度 virtual HRESULT WINAPI strLen(long* pLenSrc) = 0; /// 在源串中查找目标串 virtual HRESULT WINAPI find(const char* pszToFind, long* pPosIndex) = 0; }; // {41BB6FBB-420E-43DD-B17B-61B62A70EBD3} static const GUID IID_IFastString = { 0x41bb6fbb, 0x420e, 0x43dd, { 0xb1, 0x7b, 0x61, 0xb6, 0x2a, 0x70, 0xeb, 0xd3 } }; #endif // !defined(AFX_IFASTSTRING_H__DD942C83_85A9_4168_BC80_8B64F8E8D032__INCLUDED_)
// INormalString.h: interface for the INormalString class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_INORMALSTRING_H__66C198A8_C00F_4D18_A19A_D5BD2ACC55E3__INCLUDED_) #define AFX_INORMALSTRING_H__66C198A8_C00F_4D18_A19A_D5BD2ACC55E3__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "IFastString.h" struct INormalString : public IFastString { /// 得到设置的串长度, 现算, 比较慢 virtual HRESULT WINAPI strLenEx(long* pLenSrc) = 0; }; // {72A9084D-29B1-4645-92FE-9D9C19E17F04} static const GUID IID_INormalString = { 0x72a9084d, 0x29b1, 0x4645, { 0x92, 0xfe, 0x9d, 0x9c, 0x19, 0xe1, 0x7f, 0x4 } }; #endif // !defined(AFX_INORMALSTRING_H__66C198A8_C00F_4D18_A19A_D5BD2ACC55E3__INCLUDED_)
// The following ifdef block is the standard way of creating macros which make exporting // from a DLL simpler. All files within this DLL are compiled with the MYCOMDLL_EXPORTS // symbol defined on the command line. this symbol should not be defined on any project // that uses this DLL. This way any other project whose source files include this file see // MYCOMDLL_API functions as being imported from a DLL, wheras this DLL sees symbols // defined with this macro as being exported. #ifdef MYCOMDLL_EXPORTS #define MYCOMDLL_API __declspec(dllexport) #else #define MYCOMDLL_API __declspec(dllimport) #endif extern HANDLE g_hModule;
// MyFastString.h: interface for the CMyFastString class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_MYFASTSTRING_H__0FEBBA43_6B8E_4775_82A4_56D8B2BD799C__INCLUDED_) #define AFX_MYFASTSTRING_H__0FEBBA43_6B8E_4775_82A4_56D8B2BD799C__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "IFastString.h" class CMyFastString : public IFastString { public: CMyFastString(); ~CMyFastString(); ///< COM类析构函数不能为虚函数 /// IComUnknown's interface virtual HRESULT WINAPI QueryInterface(REFIID iid, void ** ppvObject); virtual HRESULT WINAPI AddRef(long* pRefCnt); virtual HRESULT WINAPI Release(long* pRefCnt); /// IFastString's interface virtual HRESULT WINAPI set(char* pszSrc); virtual HRESULT WINAPI get(char** ppszSrc); virtual HRESULT WINAPI strLen(long* pLenSrc); virtual HRESULT WINAPI find(const char* pszToFind, long* pPosIndex); private: static long m_lRefCnt; ///< 引用计数 char* m_pSrc; ///< 源串 long m_lLenSrc; ///< 源串长度 }; /// 每一个接口实现类有一个CLSID // {0410DE8D-B8D7-4B58-A349-5ED91FC787C9} static const GUID CLSID_CMyFastString = { 0x410de8d, 0xb8d7, 0x4b58, { 0xa3, 0x49, 0x5e, 0xd9, 0x1f, 0xc7, 0x87, 0xc9 } }; /// 接口实现类在注册表中的信息 /// 每一个接口类在注册表中都必须有单独的信息 /// IDL : Interface Description Language static const char* IDL_CMyFastString[9][3] = { {"CLSID\\{0410DE8D-B8D7-4B58-A349-5ED91FC787C9}", NULL, "CMyFastString"}, {"CLSID\\{0410DE8D-B8D7-4B58-A349-5ED91FC787C9}\\InprocServer32", NULL, (const char*)-1}, {"CLSID\\{0410DE8D-B8D7-4B58-A349-5ED91FC787C9}\\ProgID", NULL, "CMyFastStringsrv.CMyFastString.1"}, {"CLSID\\{0410DE8D-B8D7-4B58-A349-5ED91FC787C9}\\TypeLib", NULL, "{0410DE8D-B8D7-4B58-A349-5ED91FC787C9}"}, {"CMyFastStringsrv.CMyFastString", NULL, "CMyFastString"}, {"CMyFastStringsrv.CMyFastString\\CLSID", NULL, "{0410DE8D-B8D7-4B58-A349-5ED91FC787C9}"}, {"CMyFastStringsrv.CMyFastString\\CurVer", NULL, "CMyFastStringsrv.CMyFastString.1"}, {"CMyFastStringsrv.CMyFastString.1", NULL, ""}, {"CMyFastStringsrv.CMyFastString.1\\CLSID", NULL, "{0410DE8D-B8D7-4B58-A349-5ED91FC787C9}"}, }; #endif // !defined(AFX_MYFASTSTRING_H__0FEBBA43_6B8E_4775_82A4_56D8B2BD799C__INCLUDED_)
// MyFastStringClassFactory.h: interface for the CMyFastStringClassFactory class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_MYFASTSTRINGCLASSFACTORY_H__C29A6C42_34CC_4551_BEDE_F65ABD7C8A16__INCLUDED_) #define AFX_MYFASTSTRINGCLASSFACTORY_H__C29A6C42_34CC_4551_BEDE_F65ABD7C8A16__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "IComClassFactory.h" class CMyFastStringClassFactory : public IComClassFactory { public: CMyFastStringClassFactory(); ~CMyFastStringClassFactory(); ///< COM类析构函数不能为虚函数 /// IComUnknown's interface virtual HRESULT WINAPI QueryInterface(REFIID iid, void ** ppvObject); virtual HRESULT WINAPI AddRef(long* pRefCnt); virtual HRESULT WINAPI Release(long* pRefCnt); /// IComClassFactory's interface virtual HRESULT WINAPI CreateInstance(REFIID riid, void ** ppvObject); private: static long m_lRefCnt; ///< 引用计数 }; // {958D3D08-3691-4C18-9C30-BD649A93F732} static const GUID CLSID_CMyFastStringClassFactory = { 0x958d3d08, 0x3691, 0x4c18, { 0x9c, 0x30, 0xbd, 0x64, 0x9a, 0x93, 0xf7, 0x32 } }; #endif // !defined(AFX_MYFASTSTRINGCLASSFACTORY_H__C29A6C42_34CC_4551_BEDE_F65ABD7C8A16__INCLUDED_)
// MyNormalStringClassFactory.h: interface for the CMyNormalStringClassFactory class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_MYNORMALSTRINGCLASSFACTORY_H__B0F5D800_A17D_4F61_9C6F_DE9E0DBCBF1A__INCLUDED_) #define AFX_MYNORMALSTRINGCLASSFACTORY_H__B0F5D800_A17D_4F61_9C6F_DE9E0DBCBF1A__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "MyFastStringClassFactory.h" class CMyNormalStringClassFactory : public CMyFastStringClassFactory { public: CMyNormalStringClassFactory(); ~CMyNormalStringClassFactory(); ///< COM类析构函数不能为虚函数 virtual HRESULT WINAPI QueryInterface(REFIID iid, void ** ppvObject); virtual HRESULT WINAPI CreateInstance(REFIID riid, void ** ppvObject); }; // {E9E73FE9-A1DD-4A02-A73C-EF3CA8176B2A} static const GUID CLSID_CMyNormalStringClassFactory = { 0xe9e73fe9, 0xa1dd, 0x4a02, { 0xa7, 0x3c, 0xef, 0x3c, 0xa8, 0x17, 0x6b, 0x2a } }; #endif // !defined(AFX_MYNORMALSTRINGCLASSFACTORY_H__B0F5D800_A17D_4F61_9C6F_DE9E0DBCBF1A__INCLUDED_)
// NormalString.h: interface for the CNormalString class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_NORMALSTRING_H__3E1B2625_5AF8_4034_B9DF_AA58BE0361D0__INCLUDED_) #define AFX_NORMALSTRING_H__3E1B2625_5AF8_4034_B9DF_AA58BE0361D0__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "INormalString.h" class CNormalString : public INormalString { public: CNormalString(); ~CNormalString(); ///< COM类析构函数不能为虚函数 /// IComUnknown's interface virtual HRESULT WINAPI QueryInterface(REFIID iid, void ** ppvObject); virtual HRESULT WINAPI AddRef(long* pRefCnt); virtual HRESULT WINAPI Release(long* pRefCnt); /// IFastString's interface virtual HRESULT WINAPI set(char* pszSrc); virtual HRESULT WINAPI get(char** ppszSrc); virtual HRESULT WINAPI strLen(long* pLenSrc); virtual HRESULT WINAPI find(const char* pszToFind, long* pPosIndex); /// INormalString's interface virtual HRESULT WINAPI strLenEx(long* pLenSrc); private: static long m_lRefCnt; ///< 引用计数 char* m_pSrc; ///< 源串 }; // {50D0C1CE-285D-40D1-B010-F1E36EDD54E4} static const GUID CLSID_CNormalString = { 0x50d0c1ce, 0x285d, 0x40d1, { 0xb0, 0x10, 0xf1, 0xe3, 0x6e, 0xdd, 0x54, 0xe4 } }; static const char* IDL_CNormalString[9][3] = { {"CLSID\\{50D0C1CE-285D-40D1-B010-F1E36EDD54E4}", NULL, "CNormalString"}, {"CLSID\\{50D0C1CE-285D-40D1-B010-F1E36EDD54E4}\\InprocServer32", NULL, (const char*)-1}, {"CLSID\\{50D0C1CE-285D-40D1-B010-F1E36EDD54E4}\\ProgID", NULL, "CNormalStringsrv.CNormalString.1"}, {"CLSID\\{50D0C1CE-285D-40D1-B010-F1E36EDD54E4}\\TypeLib", NULL, "{50D0C1CE-285D-40D1-B010-F1E36EDD54E4}"}, {"CNormalStringsrv.CNormalString", NULL, "CNormalString"}, {"CNormalStringsrv.CNormalString\\CLSID", NULL, "{50D0C1CE-285D-40D1-B010-F1E36EDD54E4}"}, {"CNormalStringsrv.CNormalString\\CurVer", NULL, "CNormalStringsrv.CNormalString.1"}, {"CNormalStringsrv.CNormalString.1", NULL, ""}, {"CNormalStringsrv.CNormalString.1\\CLSID", NULL, "{50D0C1CE-285D-40D1-B010-F1E36EDD54E4}"}, }; #endif // !defined(AFX_NORMALSTRING_H__3E1B2625_5AF8_4034_B9DF_AA58BE0361D0__INCLUDED_)
// FactoryMaker.cpp: implementation of the CFactoryMaker class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "FactoryMaker.h" #include "MyNormalStringClassFactory.h" #include "NormalString.h" #include "MyFastStringClassFactory.h" #include "MyFastString.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// IComClassFactory* Maker_CMyNormalStringClassFactory() { return new CMyNormalStringClassFactory; } IComClassFactory* Maker_CMyFastStringClassFactory() { return new CMyFastStringClassFactory; } CFactoryMaker::CFactoryMaker() { m_deqInfo.push_back(CComClassInfo(CLSID_CNormalString, &Maker_CMyNormalStringClassFactory)); m_deqInfo.push_back(CComClassInfo(CLSID_CMyFastString, &Maker_CMyFastStringClassFactory)); } CFactoryMaker::~CFactoryMaker() { } IComClassFactory* CFactoryMaker::gen(REFCLSID rclsid) { IComClassFactory* pComClassFactory = NULL; std::deque<CComClassInfo>::iterator it; CComClassInfo info; for (it = m_deqInfo.begin(); it != m_deqInfo.end(); it++) { info = *it; if ((0 == memcmp(&rclsid, &(info.m_guid), sizeof(GUID))) && (NULL != info.m_pfn) && (NULL != *info.m_pfn)) { pComClassFactory = (*info.m_pfn)(); break; } } return pComClassFactory; }
// Helper.cpp: implementation of the CHelpr class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Helper.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// extern HANDLE g_hModule; STDAPI DllRegisterServer_RegTbl(const char** szRegTable, int iAryCnt) { const char* pszKeyName = NULL; const char* pszValueName = NULL; const char* pszValue = NULL; char szPath[MAX_PATH] = {'\0'}; HKEY hKey = NULL; for (int i = 0; i < iAryCnt; i++) { pszKeyName = *(szRegTable + i*3 + 0); pszValueName = *(szRegTable + i*3 + 1); pszValue = *(szRegTable + i*3 + 2); if (pszValue == (char*)-1) { GetModuleFileName((HMODULE)g_hModule, szPath, sizeof(szPath)); pszValue = szPath; } hKey = NULL; ::RegCreateKey(HKEY_CLASSES_ROOT, pszKeyName, &hKey); ::RegSetValue(hKey, pszValueName, REG_SZ, pszValue, strlen(pszValue)); ::RegCloseKey(hKey); } return S_OK; } STDAPI DllUnRegisterServer_RegTbl(const char** szRegTable, int iAryCnt) { const char* pszKeyName = NULL; const char* pszValueName = NULL; const char* pszValue = NULL; char szPath[MAX_PATH] = {'\0'}; HKEY hKey = NULL; for (int i = iAryCnt - 1; i >= 0; i--) { pszKeyName = *(szRegTable + i*3 + 0); ::RegDeleteKey(HKEY_CLASSES_ROOT, pszKeyName); } return S_OK; }
// MyComDll.cpp : Defines the entry point for the DLL application. // #include "stdafx.h" #include "MyComDll.h" #include "FactoryMaker.h" #include "MyFastString.h" #include "NormalString.h" #include "Helper.h" HANDLE g_hModule = NULL; BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { g_hModule = hModule; } break; case DLL_THREAD_ATTACH: { } break; case DLL_THREAD_DETACH: { } break; case DLL_PROCESS_DETACH: { } break; default: break; } return TRUE; } STDAPI DllCanUnloadNow() { return S_OK; } STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { IComClassFactory* pComClassFactory = NULL; HRESULT hr = S_OK; CFactoryMaker FactoryMaker; do { if (NULL == ppv) { hr = E_POINTER; break; } pComClassFactory = FactoryMaker.gen(rclsid); if (NULL != pComClassFactory) { hr = pComClassFactory->QueryInterface(riid, ppv); } else { hr = E_NOINTERFACE; } } while (0); return hr; } STDAPI DllRegisterServer(void) { DllRegisterServer_RegTbl( &IDL_CMyFastString[0][0], sizeof(IDL_CMyFastString) / sizeof(IDL_CMyFastString[0])); DllRegisterServer_RegTbl( &IDL_CNormalString[0][0], sizeof(IDL_CNormalString) / sizeof(IDL_CNormalString[0])); return S_OK; } STDAPI DllUnregisterServer(void) { DllUnRegisterServer_RegTbl( &IDL_CMyFastString[0][0], sizeof(IDL_CMyFastString) / sizeof(IDL_CMyFastString[0])); DllUnRegisterServer_RegTbl( &IDL_CNormalString[0][0], sizeof(IDL_CNormalString) / sizeof(IDL_CNormalString[0])); return S_OK; }
// MyFastString.cpp: implementation of the CMyFastString class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "MyFastString.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// long CMyFastString::m_lRefCnt = 0; CMyFastString::CMyFastString() { m_pSrc = NULL; m_lLenSrc = 0; } CMyFastString::~CMyFastString() { } HRESULT WINAPI CMyFastString::QueryInterface(REFIID iid, void ** ppvObject) { HRESULT hr = S_OK; do { if (NULL == ppvObject) { hr = ERROR_DS_PARAM_ERROR; break; } if (0 == memcmp(&iid, &IID_IComUnknown, sizeof(GUID))) { *ppvObject = (IComUnknown*)this; } else if (0 == memcmp(&iid, &IID_IFastString, sizeof(GUID))) { *ppvObject = (IFastString*)this; } else { hr = E_NOINTERFACE; } } while (0); return hr; } HRESULT WINAPI CMyFastString::AddRef(long* pRefCnt) { HRESULT hr = S_OK; do { if (NULL == pRefCnt) { hr = ERROR_DS_PARAM_ERROR; break; } *pRefCnt = InterlockedIncrement(&m_lRefCnt); } while (0); return hr; } HRESULT WINAPI CMyFastString::Release(long* pRefCnt) { HRESULT hr = S_OK; do { if (NULL == pRefCnt) { hr = ERROR_DS_PARAM_ERROR; break; } *pRefCnt = InterlockedDecrement(&m_lRefCnt); if (*pRefCnt <= 0) { /// when delete this, don't touch any thing about the class delete this; return S_OK; } } while (0); return hr; } HRESULT WINAPI CMyFastString::set(char* pszSrc) { HRESULT hr = S_OK; m_pSrc = pszSrc; m_lLenSrc = (NULL != m_pSrc) ? strlen(m_pSrc) : 0; return hr; } HRESULT WINAPI CMyFastString::get(char** ppszSrc) { HRESULT hr = S_OK; do { if (NULL == ppszSrc) { hr = ERROR_DS_PARAM_ERROR; break; } *ppszSrc = m_pSrc; } while (0); return hr; } HRESULT WINAPI CMyFastString::strLen(long* pLenSrc) { HRESULT hr = S_OK; do { if (NULL == pLenSrc) { hr = ERROR_DS_PARAM_ERROR; break; } *pLenSrc = m_lLenSrc; } while (0); return hr; } HRESULT WINAPI CMyFastString::find(const char* pszToFind, long* pPosIndex) { HRESULT hr = S_OK; do { if ((NULL == pszToFind) || (NULL == pPosIndex)) { hr = ERROR_DS_PARAM_ERROR; break; } if (NULL == m_pSrc) { hr = S_FALSE; break; } *pPosIndex = (long)strstr(m_pSrc, pszToFind) - (long)m_pSrc; } while (0); return hr; }
// MyFastStringClassFactory.cpp: implementation of the CMyFastStringClassFactory class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "MyFastStringClassFactory.h" #include "MyFastString.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// long CMyFastStringClassFactory::m_lRefCnt = 0; CMyFastStringClassFactory::CMyFastStringClassFactory() { } CMyFastStringClassFactory::~CMyFastStringClassFactory() { } HRESULT WINAPI CMyFastStringClassFactory::QueryInterface(REFIID iid, void ** ppvObject) { HRESULT hr = S_OK; do { if (NULL == ppvObject) { hr = ERROR_DS_PARAM_ERROR; break; } if (0 == memcmp(&iid, &IID_IComUnknown, sizeof(GUID))) { *ppvObject = (IComUnknown*)this; } else if (0 == memcmp(&iid, &IID_IComClassFactory, sizeof(GUID))) { *ppvObject = (IComClassFactory*)this; } else if (0 == memcmp(&iid, &IID_IFastString, sizeof(GUID))) { *ppvObject = (IComClassFactory*)this; } else { hr = E_NOINTERFACE; } } while (0); return hr; } HRESULT WINAPI CMyFastStringClassFactory::AddRef(long* pRefCnt) { HRESULT hr = S_OK; do { if (NULL == pRefCnt) { hr = ERROR_DS_PARAM_ERROR; break; } *pRefCnt = InterlockedIncrement(&m_lRefCnt); } while (0); return hr; } HRESULT WINAPI CMyFastStringClassFactory::Release(long* pRefCnt) { HRESULT hr = S_OK; do { if (NULL == pRefCnt) { hr = ERROR_DS_PARAM_ERROR; break; } *pRefCnt = InterlockedDecrement(&m_lRefCnt); if (*pRefCnt <= 0) { /// when delete this, don't touch any thing about the class delete this; return S_OK; } } while (0); return hr; } HRESULT WINAPI CMyFastStringClassFactory::CreateInstance(REFIID riid, void ** ppvObject) { static CMyFastString* pObject = NULL; HRESULT hr = S_OK; do { if (NULL == ppvObject) { hr = ERROR_DS_PARAM_ERROR; break; } if (0 == memcmp(&IID_IFastString, &riid, sizeof(GUID))) { if (NULL == pObject) { pObject = new CMyFastString(); if (NULL == pObject) { hr = ERROR_NOT_ENOUGH_MEMORY; break; } } *ppvObject = pObject; break; } else { hr = ERROR_DS_PARAM_ERROR; break; } } while (0); return hr; }
// MyNormalStringClassFactory.cpp: implementation of the CMyNormalStringClassFactory class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "MyNormalStringClassFactory.h" #include "NormalString.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CMyNormalStringClassFactory::CMyNormalStringClassFactory() { } CMyNormalStringClassFactory::~CMyNormalStringClassFactory() { } HRESULT WINAPI CMyNormalStringClassFactory::QueryInterface(REFIID iid, void ** ppvObject) { HRESULT hr = S_OK; do { if (NULL == ppvObject) { hr = ERROR_DS_PARAM_ERROR; break; } if (0 == memcmp(&iid, &IID_IComUnknown, sizeof(GUID))) { *ppvObject = (IComUnknown*)this; } else if (0 == memcmp(&iid, &IID_IComClassFactory, sizeof(GUID))) { *ppvObject = (IComClassFactory*)this; } else if (0 == memcmp(&iid, &IID_INormalString, sizeof(GUID))) { *ppvObject = (IComClassFactory*)this; } else { hr = E_NOINTERFACE; } } while (0); return hr; } HRESULT WINAPI CMyNormalStringClassFactory::CreateInstance(REFIID riid, void ** ppvObject) { static CNormalString* pObject = NULL; HRESULT hr = S_OK; do { if (NULL == ppvObject) { hr = ERROR_DS_PARAM_ERROR; break; } if (0 == memcmp(&IID_INormalString, &riid, sizeof(GUID))) { if (NULL == pObject) { pObject = new CNormalString(); if (NULL == pObject) { hr = ERROR_NOT_ENOUGH_MEMORY; break; } } *ppvObject = pObject; break; } else { hr = ERROR_DS_PARAM_ERROR; break; } } while (0); return hr; }
// NormalString.cpp: implementation of the CNormalString class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "NormalString.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// long CNormalString::m_lRefCnt = 0; CNormalString::CNormalString() { m_pSrc = NULL; } CNormalString::~CNormalString() { } HRESULT WINAPI CNormalString::QueryInterface(REFIID iid, void ** ppvObject) { HRESULT hr = S_OK; do { if (NULL == ppvObject) { hr = ERROR_DS_PARAM_ERROR; break; } if (0 == memcmp(&iid, &IID_IComUnknown, sizeof(GUID))) { *ppvObject = (IComUnknown*)this; } else if (0 == memcmp(&iid, &IID_IFastString, sizeof(GUID))) { *ppvObject = (IFastString*)this; } else { hr = E_NOINTERFACE; } } while (0); return hr; } HRESULT WINAPI CNormalString::AddRef(long* pRefCnt) { HRESULT hr = S_OK; do { if (NULL == pRefCnt) { hr = ERROR_DS_PARAM_ERROR; break; } *pRefCnt = InterlockedIncrement(&m_lRefCnt); } while (0); return hr; } HRESULT WINAPI CNormalString::Release(long* pRefCnt) { HRESULT hr = S_OK; do { if (NULL == pRefCnt) { hr = ERROR_DS_PARAM_ERROR; break; } *pRefCnt = InterlockedDecrement(&m_lRefCnt); if (*pRefCnt <= 0) { /// when delete this, don't touch any thing about the class delete this; return S_OK; } } while (0); return hr; } HRESULT WINAPI CNormalString::set(char* pszSrc) { HRESULT hr = S_OK; m_pSrc = pszSrc; return hr; } HRESULT WINAPI CNormalString::get(char** ppszSrc) { HRESULT hr = S_OK; do { if (NULL == ppszSrc) { hr = ERROR_DS_PARAM_ERROR; break; } *ppszSrc = m_pSrc; } while (0); return hr; } HRESULT WINAPI CNormalString::strLen(long* pLenSrc) { return strLenEx(pLenSrc); } HRESULT WINAPI CNormalString::strLenEx(long* pLenSrc) { HRESULT hr = S_OK; do { if (NULL == pLenSrc) { hr = ERROR_DS_PARAM_ERROR; break; } *pLenSrc = (NULL != m_pSrc) ? strlen(m_pSrc) : 0; } while (0); return hr; } HRESULT WINAPI CNormalString::find(const char* pszToFind, long* pPosIndex) { HRESULT hr = S_OK; do { if ((NULL == pszToFind) || (NULL == pPosIndex)) { hr = ERROR_DS_PARAM_ERROR; break; } if (NULL == m_pSrc) { hr = S_FALSE; break; } *pPosIndex = (long)strstr(m_pSrc, pszToFind) - (long)m_pSrc; } while (0); return hr; }
测试程序
// test.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <windows.h> #include <tchar.h> #include <process.h> #include <conio.h> #include "../IComClassFactory.h" #include "../MyFastString.h" #include "../NormalString.h" void fnTest_ComDLLReg(); void fnTest_ComDLLUnReg(); void fnTest_CallCMyFastString(); void fnTest_CNormalString(); int main(int argc, char* argv[]) { char c = '\0'; do { printf("\r\n"); printf("1 : ComDllReg\n"); printf("2 : ComDllUnReg\n"); printf("3 : Call CMyFastString by register\n"); printf("4 : Call CNormalString by register\n"); printf("q : quit program\n"); printf("========================================\n"); fflush(stdin); c = _getch(); if ('q' == c) { break; } else if ('1' == c) { fnTest_ComDLLReg(); } else if ('2' == c) { fnTest_ComDLLUnReg(); } else if ('3' == c) { fnTest_CallCMyFastString(); } else if ('4' == c) { fnTest_CNormalString(); } else { printf("input error, please try again\n"); } } while (1); printf("the END\n"); system("pause"); return 0; } /* HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{0410DE8D-B8D7-4B58-A349-5ED91FC787C9}\InprocServer32 默认值 = D:\ls\xx\project\MyComDll\Debug\MyComDll.dll */ typedef HRESULT (__stdcall *PFN_DllGetClassObject)(REFCLSID rclsid, REFIID riid, LPVOID * ppv); void fnTest_CNormalString() { HKEY hKey = NULL; LONG lRc = ERROR_SUCCESS; TCHAR szBuf[MAX_PATH] = {_T('\0')}; DWORD dwLen = sizeof(szBuf) / sizeof(szBuf[0]); const TCHAR* pszKeyName = _T("Wow6432Node\\CLSID\\{50D0C1CE-285D-40D1-B010-F1E36EDD54E4}\\InprocServer32"); HMODULE hDll = NULL; PFN_DllGetClassObject pfnDllGetClassObject = NULL; IComClassFactory* pFactory = NULL; INormalString* pNormalString = NULL; LONG lLen = 0; LONG lRefCnt = 0; char* pMsg = NULL; HRESULT hr = S_OK; do { lRc = ::RegOpenKey(HKEY_CLASSES_ROOT, pszKeyName, &hKey); if (ERROR_SUCCESS != lRc) { break; } lRc = ::RegQueryValueEx(hKey, NULL, NULL, NULL, (BYTE*)szBuf, &dwLen); if (ERROR_SUCCESS != lRc) { break; } lRc = ::RegCloseKey(hKey); // now szBuf is D:\ls\xx\project\MyComDll\Debug\MyComDll.dll hDll = LoadLibrary(szBuf); if (NULL == hDll) { break; } pfnDllGetClassObject = (PFN_DllGetClassObject)GetProcAddress(hDll, _T("DllGetClassObject")); if (NULL == pfnDllGetClassObject) { break; } hr = pfnDllGetClassObject(CLSID_CNormalString, IID_INormalString, (void**)&pFactory); if ((S_OK != hr) || (NULL == pFactory)) { break; } pFactory->AddRef(&lRefCnt); hr = pFactory->CreateInstance(IID_INormalString, (void**)&pNormalString); if ((S_OK != hr) || (NULL == pNormalString)) { pFactory->Release(&lRefCnt); break; } pFactory->Release(&lRefCnt); pNormalString->AddRef(&lRefCnt); hr = pNormalString->set("Hello world normal"); if (S_OK != hr) { pNormalString->Release(&lRefCnt); break; } hr = pNormalString->get(&pMsg); if (S_OK != hr) { pNormalString->Release(&lRefCnt); break; } hr = pNormalString->strLen(&lLen); if (S_OK != hr) { pNormalString->Release(&lRefCnt); break; } pNormalString->Release(&lRefCnt); _tprintf(_T("%s, lLen = %d\n"), pMsg, lLen); } while (0); if (NULL != hDll) { FreeLibrary(hDll); } } void fnTest_CallCMyFastString() { HKEY hKey = NULL; LONG lRc = ERROR_SUCCESS; TCHAR szBuf[MAX_PATH] = {_T('\0')}; DWORD dwLen = sizeof(szBuf) / sizeof(szBuf[0]); const TCHAR* pszKeyName = _T("Wow6432Node\\CLSID\\{0410DE8D-B8D7-4B58-A349-5ED91FC787C9}\\InprocServer32"); HMODULE hDll = NULL; PFN_DllGetClassObject pfnDllGetClassObject = NULL; IComClassFactory* pFactory = NULL; IFastString* pFastString = NULL; LONG lLen = 0; LONG lRefCnt = 0; char* pMsg = NULL; HRESULT hr = S_OK; do { lRc = ::RegOpenKey(HKEY_CLASSES_ROOT, pszKeyName, &hKey); if (ERROR_SUCCESS != lRc) { break; } lRc = ::RegQueryValueEx(hKey, NULL, NULL, NULL, (BYTE*)szBuf, &dwLen); if (ERROR_SUCCESS != lRc) { break; } lRc = ::RegCloseKey(hKey); // now szBuf is D:\ls\xx\project\MyComDll\Debug\MyComDll.dll hDll = LoadLibrary(szBuf); if (NULL == hDll) { break; } pfnDllGetClassObject = (PFN_DllGetClassObject)GetProcAddress(hDll, _T("DllGetClassObject")); if (NULL == pfnDllGetClassObject) { break; } hr = pfnDllGetClassObject(CLSID_CMyFastString, IID_IFastString, (void**)&pFactory); if ((S_OK != hr) || (NULL == pFactory)) { break; } pFactory->AddRef(&lRefCnt); hr = pFactory->CreateInstance(IID_IFastString, (void**)&pFastString); if ((S_OK != hr) || (NULL == pFastString)) { pFactory->Release(&lRefCnt); break; } pFactory->Release(&lRefCnt); pFastString->AddRef(&lRefCnt); hr = pFastString->set("Hello world"); if (S_OK != hr) { pFastString->Release(&lRefCnt); break; } hr = pFastString->get(&pMsg); if (S_OK != hr) { pFastString->Release(&lRefCnt); break; } hr = pFastString->strLen(&lLen); if (S_OK != hr) { pFastString->Release(&lRefCnt); break; } pFastString->Release(&lRefCnt); _tprintf(_T("%s, lLen = %d\n"), pMsg, lLen); } while (0); if (NULL != hDll) { FreeLibrary(hDll); } } typedef HRESULT (STDAPICALLTYPE *PFN_DllRegisterServer)(void); void fnTest_ComDLLReg() { TCHAR cBuf[MAX_PATH] = {_T('\0')}; TCHAR* pBuf = NULL; HMODULE hDll = NULL; PFN_DllRegisterServer pfnDllRegisterServer = NULL; HRESULT hr = S_OK; do { GetModuleFileName(NULL, cBuf, sizeof(cBuf) / sizeof(cBuf[0])); pBuf = _tcsrchr(cBuf, _T('\\')); if (NULL == pBuf) { _tprintf(_T("error : GetModuleFileName\n")); break; } _tcscpy(pBuf + 1, _T("MyComDll.dll")); _tprintf(_T("COM DLL : %s\n"), cBuf); hDll = LoadLibrary(cBuf); if (NULL == hDll) { _tprintf("error : LoadLibrary\n"); break; } pfnDllRegisterServer = (PFN_DllRegisterServer)GetProcAddress(hDll, _T("DllRegisterServer")); if (NULL == pfnDllRegisterServer) { _tprintf(_T("error : can't find DllRegisterServer\n")); break; } hr = pfnDllRegisterServer(); _tprintf(_T("DllRegisterServer %s\n"), (S_OK == hr) ? _T("success") : _T("failed")); } while (0); if (NULL != hDll) { FreeLibrary(hDll); } } typedef HRESULT (__stdcall *PFN_DllUnregisterServer)(void); void fnTest_ComDLLUnReg() { TCHAR cBuf[MAX_PATH] = {_T('\0')}; TCHAR* pBuf = NULL; HMODULE hDll = NULL; PFN_DllUnregisterServer pfnDllUnregisterServer = NULL; HRESULT hr = S_OK; do { GetModuleFileName(NULL, cBuf, sizeof(cBuf) / sizeof(cBuf[0])); pBuf = _tcsrchr(cBuf, _T('\\')); if (NULL == pBuf) { _tprintf(_T("error : GetModuleFileName\n")); break; } _tcscpy(pBuf + 1, _T("MyComDll.dll")); _tprintf(_T("COM DLL : %s\n"), cBuf); hDll = LoadLibrary(cBuf); if (NULL == hDll) { _tprintf("error : LoadLibrary\n"); break; } pfnDllUnregisterServer = (PFN_DllUnregisterServer)GetProcAddress(hDll, _T("DllUnregisterServer")); if (NULL == pfnDllUnregisterServer) { _tprintf(_T("error : can't find DllUnregisterServer\n")); break; } hr = pfnDllUnregisterServer(); _tprintf(_T("DllUnregisterServer %s\n"), (S_OK == hr) ? _T("success") : _T("failed")); } while (0); if (NULL != hDll) { FreeLibrary(hDll); } }
相关文章推荐
- CDISC SDTM CM domain 学习笔记
- JSP页面实现servlet过滤器与servlet监听器(JSP中级技术)
- PHP 布尔假值情况
- ORACLE 闪回恢复区(Flashback recovery area)与undo tablespace
- 操作系统实验2-作业调度2.0
- java第五次作业
- leetCode(62)-Reverse Integer
- nfs限定挂载过来以后的用户为本地用户
- 标准OAM注册扩展OAM注册以及扩展OAM报文分析
- MogileFS
- leetCode(62)-Reverse Integer
- leetCode(62)-Reverse Integer
- iOS常用的数学函数
- java 基础加强(myeclipse,debug,junit,JDK5新特性,反射)
- LeetCode 91. Decode Ways
- 读书笔记-神经网络与深度学习(一)-使用神经网络识别手写数字
- 42.leetcode题目:169. Majority Element(还有一种方法待做)
- Spring中的设计模式(转载)
- 我所亲历的北京抢房潮
- Android之UI--打造万能自定义Dialog