您的位置:首页 > 其它

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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: