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

📄 opctest.cpp

📁 工业标准通讯OPC协议的客户端测试源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// opctest.cpp
//
// (c) Copyright 1998 The OPC Foundation
// ALL RIGHTS RESERVED.
//
// DISCLAIMER:
//  This sample code is provided by the OPC Foundation solely to assist 
//  in understanding the OPC Specifications and may be used
//  as set forth in the License Grant section of the OPC Specification.
//  This code is provided as-is and without warranty or support of any sort
//  and is subject to the Warranty and Liability Disclaimers which appear
//  in the printed OPC Specification.
//
// CREDITS:
//  This code was generously provided to the OPC Foundation by
//  Al Chisholm, Intellution Inc.
//
// CONTENTS:
//
// Very simple example of an OPC Client program.
// It shows the proper use of most of the interfaces and methods
// including use of Variants and proper Freeing of returned memory!
//
// The main goal of the program is to try to call every method
// on every interface to show proper use of the method and proper freeing
// of returned parameters.
//
// The secondary goal of this program is to serve as a general purpose
// test program for OPC Custom Servers and to try to allow the User
// to perform a reasonable (but certainly not exhaustive) test of 
// the server behavior. It is NOT very user friendly in this regard.
// But it should still be fairly useful.
//
// This test program can be used to connect to and 
// test the basic functionality of any OPC Custom Server.
//
// Note that it creates 2 groups, adds 2 tags to each group,
// and reads the data for both tags.
// The idea is that if 1 works it proves very little
// but if '2' work then probably 'n' will work.
//
// What is missing from this version:
//   Some of the OPTIONAL interfaces are missing.
//   A few of the less commonly used methods are not tested.
//
//
// Modification Log:
//	Vers    Date   By    Notes
//	----  -------- ---   -----
//	0.00  11/18/96 ACC
//	      12/01/96 acc   add PersistFile, Enumerators, Item fuctions
//                       Separate INPROC and LOCAL server tests
//	0.01  02/08/97 acc   Fix memory leaks (see acc001)
//	0.02  02/28/97 acc   Add ability to enter server and node name
//                      and to enter ItemID and AccessPaths
//	                     and to connect via DCOM (CreateRemoteServer)
//                       Correct some error messages
// 0.90  05/03/97 acc   Add ConnectionPoint Capability (early)
//                       & many additional tests
// 1.0a  08/01/97 acc   add TryBrowse, remove server::enumunknown
// 2.00  09/01/97 acc   add TryParms, finalize connection points, ASYNCIO2
//                      fix bugs in TryItemReadWrite
//       11/10/97 acc   test sync read from both cache and device
//       01/14/98 acc   update per final spec.
//
//                      todo: add tests for NULL pointers and Strings where allowed
//                      to insure they marshall properly.
//

#include <stdio.h>
#include <conio.h>
#include "opccomn.h"	// Include the GENERIC OPC header file
#include "opcda.h"	// Include the GENERIC OPC header file
#include "wcsutil.h"
#include "OLECTL.h"
#include "COMCAT.h"


//---------------------------------------------------------
// Local Functions

void LocalInit(void);
void LocalCleanup(void);

IUnknown * CreateRemoteOPCServer(WCHAR* szProgID, WCHAR*szNodeName);
IUnknown * CreateInprocOPCServer(WCHAR* szProgID);
IUnknown * CreateLocalOPCServer(WCHAR* szProgID);

void ShowDAList(CATID);
void TryIUnknown(IUnknown * pOPC);
void TryOPCServer(IOPCServer * pOPC);
void TryPersistFile(IPersistFile * pOPC);
void TryGetErrorString(IOPCServer * pOPC);
void TryGetStatus(IOPCServer * pOPC);
void TryAddGroup(IOPCServer * pOPC);
void TryRemoveGroup(IOPCServer * pOPC);
void TryEnumString(IOPCServer * pOPC);
void TryGetByName(IOPCServer * pOPC, LPOLESTR name);
void TryEnumUnknown1(IOPCServer * pOPC);

void TryGSM( IOPCGroupStateMgt * pGRP1 );
extern	OPCHANDLE TryGetGroupState(IOPCGroupStateMgt * pGRP);

void TestGroup(void);

void TryItemFunctions(IOPCGroupStateMgt * pGRP);

void TryItemReadWrite(IOPCSyncIO *pSIO, int nItem, OPCHANDLE *sh);
void TryEnumItemAttributes(IOPCItemMgt * pOPC);

extern void TryIM( IOPCItemMgt * pIM);
extern void TryConnectionPoint(IOPCGroupStateMgt * pGRP, int nItem, OPCHANDLE *sh);	//V2.0
extern void TryDataObject(IOPCGroupStateMgt * pGRP, int nItem, OPCHANDLE *sh);
extern void TryBrowse(IOPCBrowseServerAddressSpace * pBAS);
extern void TryParams(IOPCItemProperties * pPRM);
extern void TryCOMN(IOPCCommon * pPRM);
extern int  TrySvrCPC(IConnectionPointContainer * pPRM);

void	report( char*n, HRESULT r);
void	DumpVariant(VARIANT *v);



// Global interface to the COM memory manager
IMalloc *pIMalloc;

// Some Global Strings for use in Group/Item Testing
//
WCHAR	*ItemIDs[2] = {0,0};
WCHAR	*AccessPaths[2] = {0,0};
VARTYPE	dtype[2];
OPCHANDLE g_sh[2];		// Returned Server Handles for the Items
BOOL add_done = 0;


// Global list of available server interfaces
//
IUnknown *gpOPC = 0;
IOPCServer *gpOPCS = 0;
IConnectionPointContainer *gpOPC_CPC = 0;
IOPCCommon *gpOPCCOMN = 0;
IOPCBrowseServerAddressSpace *gpOPCBA = 0;
IOPCItemProperties *gpOPCPRM = 0;
IOPCServerPublicGroups *gpOPCPG = 0;
//IEnumUnknown * gpOPCEU = 0;
IPersistFile * gpOPCPF = 0;


// Catagory IDs (in opc_cats.c)
//
EXTERN_C const CATID CATID_OPCDAServer10;
EXTERN_C const CATID CATID_OPCDAServer20;

//---------------------------------------------------------
// main
void main(void)
{
	HRESULT r2, r3, r5, r6, r7, r8, r9;
	int loop, sdr;

	printf("Al Chisholm's OPC Client Demo/OPC Custom Server Test Program V2.xx\n");
	printf("Provided by Intellution Inc.\n");

	LocalInit();

	// Check for and show registered Data Access Servers
	//
	printf("DA 1.0 Servers...\n");
	ShowDAList(CATID_OPCDAServer10);
	printf("DA 2.0 Servers...\n");
	ShowDAList(CATID_OPCDAServer20);

	// Allow the user to run the test several time...
	//
	while(1)
	{
		CHAR c;
		CHAR buffer[82] = {80};
		CHAR *nptr, *pptr;
		WCHAR *node = 0;
		WCHAR *progid = 0;

		while(kbhit())getch();

		printf("Enter Server type I(inproc),L(local),R(remote), X(exit)\n");
		pptr = gets(buffer);
		c = *pptr;
		if(c == 'x') break;
		if(c == 'X') break;

		// read the common info we need for all of the tests
		//
		printf("Enter Server PROGID\n");
		pptr = gets(buffer);
		progid = WSTRFromSBCS(pptr, 0);
		

		while(kbhit())getch();
		switch(c)
		{
		case 'i':
		case 'I':
			gpOPC = CreateInprocOPCServer(progid);
			break;

		case 'l':
		case 'L':
			gpOPC = CreateLocalOPCServer(progid);
			break;

		case 'r':
		case 'R':
			printf("Enter Server NodeName\n");
			nptr = gets(buffer);
			node = WSTRFromSBCS(nptr, 0);
		
			gpOPC = CreateRemoteOPCServer(progid, node);
			break;

		default:
			break;
		}

		if(gpOPC)
		{
			printf("\nChecking Supported Server Interfaces...\n");
			// See what interfaces are supported
			//
			r2 = gpOPC->QueryInterface(IID_IOPCServer, (void**)&gpOPCS);
			r3 = gpOPC->QueryInterface(IID_IPersistFile, (void**)&gpOPCPF);
			r5 = gpOPC->QueryInterface(IID_IOPCServerPublicGroups, (void**)&gpOPCPG);
			r6 = gpOPC->QueryInterface(IID_IOPCBrowseServerAddressSpace, (void**)&gpOPCBA);
			r7 = gpOPC->QueryInterface(IID_IOPCItemProperties, (void**)&gpOPCPRM);
			r8 = gpOPC->QueryInterface(IID_IOPCCommon, (void**)&gpOPCCOMN);
			r9 = gpOPC->QueryInterface(IID_IConnectionPointContainer, (void**)&gpOPC_CPC);

			report("IUnknown.................... ", S_OK);
			report("IOPCServer.................. ", r2);
			report("IPersistFile................ ", r3);
			report("IOPCServerPublicGroups...... ", r5);
			report("IOPCBrowseServerAddressSpace ", r6);
			report("IOPCItemProperties.......... ", r7);
			report("IOPCCommon.................. ", r8);
			report("IConnectionPointContainer... ", r9);

			printf("\n");
		}

		loop = 1;
		if(gpOPC) while(loop)
		{

			// Try using the custom IOPCServer interface if present
			// and also the IDispatch interface if present
			printf("\nTest Server Interfaces...\n");
			printf("0= IUnknown...\n");
			printf("1= OPCServer...\n");
			printf("2= PersistFile...\n");
//			printf("3= IEnumUnknown...\n");
			printf("4= OPCServerPublicGroups...\n");
			printf("5= OPCBrowseServerAddressSpace...\n");
			printf("6= OPCItemProperties...\n");
			printf("7= OPCCommon...\n");
			printf("8= ConnectionPointContianer...\n");
			printf("x= Exit...\n\n");

			pptr = gets(buffer);
			c = *pptr;
			switch(c)
			{
			case '0':
				if(gpOPC)TryIUnknown( gpOPC );
				break;
			case '1':
				if(gpOPCS)TryOPCServer( gpOPCS );
				break;
			case '2':
				if(gpOPCPF)TryPersistFile( gpOPCPF );
				break;
//			case '3':

			case '4':
				printf("This test not yet implemented\n");
				break;
			case '5':
				if(gpOPCBA)TryBrowse( gpOPCBA);
				break;
			case '6':
				if(gpOPCPRM)TryParams( gpOPCPRM);
				break;
			case '7':
				if(gpOPCCOMN)TryCOMN( gpOPCCOMN);
				break;
			case '8':
				if(gpOPC_CPC) sdr = TrySvrCPC( gpOPC_CPC);
				if(sdr) 
				{
					// If shutdown request - remove groups and release server
					// Sample server will wait up to 10 seconds for this then exit anyway.
					// This 'getch' allows us to test this feature.
					//
					printf("Hit Enter to Remove Groups and release all interfaces\n");
					getch();
					TryRemoveGroup(gpOPCS);
					loop = 0;
				}
				break;
			case 'x':
				loop = 0;
				break;
			}
		}

		// Free the interfaces
		//
		if(gpOPC) gpOPC->Release();
		if(gpOPCS) gpOPCS->Release();
		if(gpOPCPF) gpOPCPF->Release();
		if(gpOPCBA) gpOPCBA->Release();
		if(gpOPCPRM) gpOPCPRM->Release();
		if(gpOPCPG) gpOPCPG->Release();
		if(gpOPCCOMN) gpOPCCOMN->Release();
		if(gpOPC_CPC) gpOPC_CPC->Release();


		WSTRFree(progid, 0);
		progid = 0;
		WSTRFree(node, 0);
		node = 0;

		WSTRFree(ItemIDs[0], 0);
		ItemIDs[0] = 0;
		WSTRFree(ItemIDs[1], 0);
		ItemIDs[1] = 0;

		WSTRFree(AccessPaths[0], 0);
		AccessPaths[0] = 0;
		WSTRFree(AccessPaths[1], 0);
		AccessPaths[1] = 0;
	}

	LocalCleanup();

	printf("Done...\n");
	getch();
	exit(0);
}



//---------------------------------------------------------
//
//
void	report( char*n, HRESULT r)
{
	printf("\t%s - ", n);
	if(FAILED(r)) printf("NOT SUPPORTED(%lx)\n", r);
	else printf("Supported\n");
}


//---------------------------------------------------------
// LocalInit													z
// This is generic initialization for a task using COM
void LocalInit(void)
{
	HRESULT	r1;
	// General COM initialization...
	//
	r1 = CoInitialize(NULL);

	if (FAILED(r1))
	{
		printf("Error from CoInitialize\n");
		exit(1);
	}

	// This is for DCOM
	//
	r1 = CoInitializeSecurity(
			NULL,   //Points to security descriptor 
			-1,     //Count of entries in asAuthSvc 
			NULL,   //Array of names to register 
			NULL,   //Reserved for future use 
			RPC_C_AUTHN_LEVEL_NONE,    //The default authentication level for proxies
			RPC_C_IMP_LEVEL_IMPERSONATE,//The default impersonation level for proxies
			NULL,                      //Reserved; must be set to  NULL 
			EOAC_NONE,                 //Additional client or server-side capabilities
			NULL                       //Reserved for future use 
			);
	if (FAILED(r1))
	{
		printf("Error from CoInitializeSecurity: %lx\n", r1);
//		CoUninitialize();
//		exit(1);
	}

	// Also get access to the COM memory manager
	//
	r1 = CoGetMalloc(MEMCTX_TASK, &pIMalloc);

	if (FAILED(r1))
	{
		printf("GetMalloc failed\n");
		CoUninitialize();
		exit(1);
	}
}



//---------------------------------------------------------
// CreateServer REMOTE
// Create the requested OPC Server - DCOM enabled!
IUnknown*	CreateRemoteOPCServer(WCHAR*szProgID, WCHAR*szNodeName)
{
	CLSID clsid;
	HRESULT r1, r2;

⌨️ 快捷键说明

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