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
原创粉丝点击