COMDLL
来源:互联网 发布:淘宝店铺怎么发布产品 编辑:程序博客网 时间:2024/05/16 19:46
前言
不利用向导,在一个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 > 1000STDAPI 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 > 1000struct 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)#endifextern 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 Languagestatic 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); }}
0 0
- COMDLL
- java 基础加强(myeclipse,debug,junit,JDK5新特性,反射)
- leetCode(62)-Reverse Integer
- ORACLE 闪回恢复区(Flashback recovery area)与undo tablespace
- 快速排序(分治法)
- spring,图片上传
- COMDLL
- CDISC SDTM CM domain 学习笔记
- Android Edittext设置光标颜色
- textview 计算宽
- activity栈管理的3种方式
- 前景检测算法_1(codebook和平均背景法)
- Windows10环境下React Native打包的个人实践
- 浅谈Android应用保护(一):Android应用逆向的基本方法
- 安卓回调详细解析