⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 impiclassfactory.cpp

📁 基于Intellution开发包的开发的OPC服务器
💻 CPP
字号:
// ImpIClassFactory.cpp
//
//   This file contains the implementation of the OPCClassFactory 
//   for the OPC sample server.
//
// Note: the combination of 'ServerDestroyed' and 'OPCServerUnload'
//   Allow this class factory to work with both EXE and DLL versions.
//   There are many ways to provide this functionality and all of them
//	 are a bit convoluted. This is modeled on BrockSchmidt 2nd edition.
//	 See Chap 5, 'The Class Factory and the Unloading Mechanism'
//	 See also DLLMAIN.CPP and EXEMAIN.CPP
//
//
//	(c) COPYRIGHT 1996-1998, INTELLUTION INC.
// ALL RIGHTS RESERVED
//
//
//	Functions defined in this module:
//
//			CImpIClassFactory::CImpIClassFactory()
//			CImpIClassFactory::~CImpIClassFactory()
//			CImpIClassFactory::AddRef()
//			CImpIClassFactory::Release()
//			CImpIClassFactory::QueryInterface()
//			CImpIClassFactory::CreateInstance()
//			CImpIClassFactory::LockServer()
//			CImpIClassFactory::ServerDestroyed()
//
//
//
// Modification Log:
//	Vers	Date     By		Notes
//	----	-------- ---	-----
//	1.1		08/26/97 jra	Created
//	1.3		03/10/98 jra	Modified to be wizard generated and driver specific.
//	7.11	02/23/99 jra	Modified CreateInstance() to save the return from QueryInterface()
//
//

#define WIN32_LEAN_AND_MEAN

#include "OpcStdAfx.h"
#include "OPCDrv.h"

void ServerDestroyed(void);

extern long	g_lObjectCount;
extern long	g_lLockCount;
extern BOOL	ServerCanUnloadNow(void);

////////////////////////////////////////////////////////////////
// OPCClassFactory()
//
// Constructor for the OPC class factory.
//
////////////////////////////////////////////////////////////////
CImpIClassFactory::CImpIClassFactory(REFCLSID rid)
{
	m_lRefCount = 0;
}


////////////////////////////////////////////////////////////////
// QueryInterface()
//
// Implementation of the standard IUnknown QueryInterface()
// for the OPC class factory.
//
////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIClassFactory::QueryInterface(REFIID riid, LPVOID* ppv)
{
	if (ppv == NULL)
	{
		return E_INVALIDARG;
	}

	*ppv = NULL;
	if (riid == IID_IUnknown)
	{
		*ppv = (IUnknown *)this;
	}
	else if (riid == IID_IClassFactory)
	{
		*ppv = (IClassFactory *)this;
	}
	else
	{
		return E_NOINTERFACE;
	}

	((IUnknown *)*ppv)->AddRef();
	return S_OK;
}


////////////////////////////////////////////////////////////////
// AddRef()
//
// Implementation of the standard IUnknown AddRef() for the 
// OPC class factory.
//
////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) CImpIClassFactory::AddRef(void)
{
	return InterlockedIncrement(&m_lRefCount);
}


////////////////////////////////////////////////////////////////
// Release()
// 
// Implementation of the standard IUnknown Release() 
// for the OPC class factory.
//
////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) CImpIClassFactory::Release(void)
{
	ULONG currentCount = InterlockedDecrement(&m_lRefCount);


	if (0 == currentCount)
	{
		delete this;
	}
	return currentCount;
}


////////////////////////////////////////////////////////////////
// CreateInstance()
//
// This function creates an instance of the OPCDrv Server.
//
////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIClassFactory::CreateInstance(LPUNKNOWN	pUnkOuter, 
											   REFIID		riid, 
											   LPVOID		*ppvObject)
{
	HRESULT hr;

	if (pUnkOuter != NULL)
	{
		return CLASS_E_NOAGGREGATION;	// Aggregation is not supported by this code
	}

	// Create a new server instance
	// We keep a count of the number created by the calling ap.
	// If that number goes to 0  (when the last interface 
	// is released and the last server is destroyed)
	// then the DLL or EXE can be unloaded.
	//
	COPCDrvServer *pServer = new COPCDrvServer(pUnkOuter, ServerDestroyed);
	if (NULL == pServer) 
	{
		return E_OUTOFMEMORY;
	}

	if (FAILED(hr = pServer->Init()))
	{
		delete pServer;
		return E_UNEXPECTED;
	}

	// jra 022399
	// Save the return from QueryInterface()
	if (FAILED(hr = pServer->QueryInterface(riid, ppvObject)))
	{
		delete pServer;
	}
	else
	{
		InterlockedIncrement(&g_lObjectCount);
	}

	return hr;
}


////////////////////////////////////////////////////////////////
// LockServer()
//
// This is a standard implementation of the IClassFactory::LockServer() 
// function that either adds or removes a lock on the server.
//
////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIClassFactory::LockServer(BOOL bLock)
{
	if (bLock)
	{
		InterlockedIncrement(&g_lLockCount);
	}
	else
	{
		InterlockedDecrement(&g_lLockCount);
		if (ServerCanUnloadNow())
		{
			OPCServerUnload();
		}
	}

	return S_OK;
}


////////////////////////////////////////////////////////////////
// ServerDestroyed()
// 
// Called by server objects when they are destroyed
// so that we can tell if there are any left 
// for the DLL or EXE to manage.
// See DLLCanUnloadNow for DLLs or OPCServerUnload for EXEs
//
////////////////////////////////////////////////////////////////
void ServerDestroyed(void)
{
	InterlockedDecrement(&g_lObjectCount);
	OPCServerUnload();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -