?? opctest.cpp
字號:
// 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 + -