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

📄 cppsimpleserver.cpp

📁 一个OPC 服务器程序
💻 CPP
字号:
// CPPSimpleServer.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "SLIKServerEvents.h"

#include <string>
using namespace std;

// 
//	This is required by <atlcom.h> - it's not used otherwise
//
CComModule _Module;
BEGIN_OBJECT_MAP(ObjectMap)
END_OBJECT_MAP()


/////////////////////////////////////////////////////////////////////////////
//
//	G L O B A L    V A R I A B L E S
//
/////////////////////////////////////////////////////////////////////////////

//
// Required to be global so we can access in Simulate routine!
//
ISLIKServerPtr g_spSlikSvr;


/////////////////////////////////////////////////////////////////////////////
//
//	H E L P E R    R O U T I N E S
//
/////////////////////////////////////////////////////////////////////////////

LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
{
    while (p1 != NULL && *p1 != NULL)
    {
        LPCTSTR p = p2;
        while (p != NULL && *p != NULL)
        {
            if (*p1 == *p)
                return CharNext(p1);
            p = CharNext(p);
        }
        p1 = CharNext(p1);
    }
    return NULL;
}


HRESULT CreateSLIKServer( ISLIKServerPtr &spSlikSvr )
{
	HRESULT hr = S_OK;
	
	//
	//	SLIK-DA is a licensed ActiveX control.  Therefore, we
	//	MUST use the IClassFactory2 interface to create an instance
	//	of the control.
	//

	CComPtr<IClassFactory2> spCF;
	try
	{
		_com_util::CheckError( CoGetClassObject( 
			__uuidof(SLIKServer), 
			CLSCTX_INPROC_SERVER, 
			NULL, 
			IID_IClassFactory2,
			(void **) &spCF
			) );

		//
		//	NOTE:	The run-time license key used here works for
		//			DEMO VERSIONS OF SLIK-DA ONLY!
		//
		spCF->CreateInstanceLic( 
			NULL, 
			NULL, 
			__uuidof(ISLIKServer), 
			L"{95A710F2-7D58-419A-92FE-D7E5E0FEC804}", 
			(void **) &spSlikSvr
			);
	}
	catch( _com_error e )
	{
		hr = e.Error();
	}

	return hr;
}


HRESULT SetupNamespace( 
	ISLIKServerPtr		&spSlikSvr
	)
{
	HRESULT hr = S_OK;
	try
	{
		_variant_t vOptionalVal;
		vOptionalVal.vt = VT_ERROR;
		_variant_t vInitVal;
		for( long i = 1; i <= 5; i++ )
		{
			vInitVal = i;
			WCHAR wsz[5];
			_ltow( i, wsz, 10 );

			//
			//	Add a few read-only tags - these source tags will change in value
			//	via simulation
			//
			wstring wstrName = L"src.tag0";
			wstrName += wsz;
			spSlikSvr->SLIKTags->Add( 
				wstrName.c_str(),
				sdaReadAccess, 
				vInitVal, 
				sdaGood,
				0,			//	Value to pass for SLIK-DA to auto-generate the timestamp
				vtMissing	//	Access paths not used - pass vtMissing 
				);
				
			//
			//	Add a few read-write tags - these target tags will NOT change
			//	via simulation
			//
			wstrName = L"trg.tag0";
			wstrName += wsz;
			spSlikSvr->SLIKTags->Add( 
				wstrName.c_str(),
				sdaReadAccess | sdaWriteAccess, 
				vInitVal, 
				sdaGood,	
				0,	
				vtMissing
				);
				
		}
	}
	catch( _com_error e )
	{
		hr = e.Error();
	}

	return hr;
}


VOID CALLBACK Simulate(
  HWND hwnd,         // handle to window
  UINT uMsg,         // WM_TIMER message
  UINT_PTR idEvent,  // timer identifier
  DWORD dwTime       // current system time
)
{
	//
	//	Simulate data changes for all read-only tags.
	//

	// NOTE: SLIKTags collection uses 1-based indices
	for( long i = 1; i <= g_spSlikSvr->SLIKTags->Count; i++ )
	{
		CComPtr<ISLIKTag> spTag;
		spTag = g_spSlikSvr->SLIKTags->Item( i );
		if( spTag->AccessPermissions == sdaReadAccess )
		{
			long lVal = spTag->GetValue();
			lVal = (lVal + 1) % 1000;

			// NOTE: passing a 0 for Timestamp means SLIK-DA will 
			// autogenerate one.
			spTag->SetVQT( lVal, sdaGood, 0 );
		}
	}
}


/////////////////////////////////////////////////////////////////////////////
//
//	M O D U L E    E N T R Y    P O I N T
//
/////////////////////////////////////////////////////////////////////////////
extern "C" int WINAPI _tWinMain(HINSTANCE hInstance, 
    HINSTANCE /*hPrevInstance*/, LPTSTR lpCmdLine, int /*nShowCmd*/)
{
	
	HRESULT hr = CoInitialize( NULL );
	_ASSERTE( SUCCEEDED( hr ) );
	
	// 
	//	The following is required to facilitate use of ATL's event handling 
	//	support.  The global CComMoudle object instance is not used otherwise.
	//
	_Module.Init( ObjectMap, hInstance );	
	
	try
	{
		_com_util::CheckError( CreateSLIKServer( g_spSlikSvr ) );
		
		//
		// Set up the SLIKServer properties - MUST be done before
		// calling RegisterServer() / UnregisterServer().
		//
		g_spSlikSvr->ProgID			= L"NDI.CPPSimpleServer.1";
		g_spSlikSvr->AppID			= L"{E33BB673-514F-4812-84AC-DEE625C97070}";
		g_spSlikSvr->CLSID			= g_spSlikSvr->AppID;
		g_spSlikSvr->AppName		= L"C++ Simple Server";
		g_spSlikSvr->Description	= L"C++ Simple Server using SLIK-DA 2.0";
		g_spSlikSvr->VendorName		= L"Northern Dynamic Inc.";
		g_spSlikSvr->MaxUpdateRate	= 500;

		//
		//	Check command line for registration switches -  an OPC server
		//	EXE must support self-registration.
		//
		BOOL bRun = TRUE;
	    TCHAR szTokens[] = _T("-/");
		LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens);
		while (lpszToken != NULL)
		{
			if (lstrcmpi(lpszToken, _T("UnregServer"))==0)
			{
				g_spSlikSvr->UnregisterServer();
				bRun = FALSE;
				break;
			}
			if (lstrcmpi(lpszToken, _T("RegServer"))==0)
			{
				g_spSlikSvr->RegisterServer();
				bRun = FALSE;
				break;
			}
			lpszToken = FindOneOf(lpszToken, szTokens);
		}

		if( bRun )
		{
			//
			//	Hook up handler for SLIKServer events
			//
			CSLIKServerEvents *pEv = new CSLIKServerEvents;
			_com_util::CheckError( pEv->DispEventAdvise( g_spSlikSvr ) );

			//
			//	Create the server tag namespace
			//
			SetupNamespace( g_spSlikSvr );

			//
			//	Start the OPC server services
			//
			g_spSlikSvr->StartServer();


			//
			//	Set up a timer to simulate data chnages
			//
			UINT uiTimer = SetTimer( NULL, 0, 500, Simulate );

			//
			//	Must dispatch Windows Messages to receive event notifications 
			//	from SLIK-DA.
			//
			MSG msg;
			while( GetMessage( &msg, NULL, 0, 0 ) )
			{
				TranslateMessage( &msg );
				DispatchMessage( &msg );
			}

			KillTimer( NULL, uiTimer );
		}
	}
	catch( _com_error e )
	{
	}
	catch(...)
	{
	}

	// Be sure to Release the ISLIKServer interface pointer before the 
	// CoUninitialize() call. Otherwise, the CComPtr<> destructor will execute
	// after the underlying SLIKServer object has been destroyed by the 
	// CoUninitialize() call, causing an access violation.
	g_spSlikSvr.Release();

	CoUninitialize();

	return 0;
}

⌨️ 快捷键说明

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