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

📄 opc_data.cpp

📁 工业标准通讯OPC协议的客户端测试源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

				r1 = pASIO->Write(MyCookiew, nItem, 
				sh, v, &tid, &hr);

				// check r1 and hr array and also free hr
				if(r1 != S_OK)
				{
					printf("Async WriteFailed:(%lx)\n", r1);
				}
				if(hr) pIMalloc->Free(hr);
			}
			if (c == 'f') 
			{
				r1 = pASIO->Refresh(MyCookie, mode, &tid);
				if (FAILED(r1))	printf("Refresh Error:%lx\n", r1);
				else printf("RefreshTID=%lx\n", tid);
			}
			if (c == 'c') 
			{
				r1 = pASIO->Cancel(tid);
				if(FAILED(r1)) printf("Cancel Error=%lx\n", r1);
			}
			if (c == 'm') 
				flip_mode(&mode);
		}else
		{
			MSG msg;
			while(PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE))
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}
	}


	// User has terminated the test
	//
	printf("Disconnecting...\n");
	r1 = pDO->DUnadvise(MyCookie);
	if (FAILED(r1))
	{
		printf("Read UnAdvise Failed:(%lx)\n", r1);
	}

	r1 = pDO->DUnadvise(MyCookiew);
	if (FAILED(r1))
	{
		printf("Write UnAdvise Failed:(%lx)\n", r1);
	}

	// Release the interfaces
	//
	pASIO->Release();
	pDO->Release();

	MyCallback -> Release();
}

static void flip_mode(OPCDATASOURCE *mode)
{
	switch(*mode)
	{
	case OPC_DS_CACHE:
		*mode = OPC_DS_DEVICE;
		printf("Mode changed to DEVICE\n");
		break;
	case OPC_DS_DEVICE:
		*mode = OPC_DS_CACHE;
		printf("Mode changed to CACHE\n");
		break;
	}
}




///////////////////////////////////////
// Handle Data Stream WITHOUT TIMESTAMP...
// This code does NOT handle arrays
//
///////////////////////////////////////
void HandleData(
	 STGMEDIUM *pSTM
)
{
	DWORD	count;
	OPCGROUPHEADER *grp;
	char *iptr;
	char *dptr;
	char *sptr;
	BOOL masterquality;
	unsigned int i;

	// Open the STGMEDIUM
	// and read the GROUP header
	//
	sptr = (char*)GlobalLock(pSTM->hGlobal);
	if(!sptr) return;

	grp = (OPCGROUPHEADER*)sptr;
	if(grp->hrStatus)
	{
		printf("\thrStatusr=%lx\n", grp->hrStatus);
		return;
	}

	// Allocate some memory into which to put the returned data
	//
	OPCHANDLE * handles;
	WORD      * quality;
	VARIANT   * values; 

	count = grp->dwItemCount;

	masterquality = 0;
	handles = new OPCHANDLE[count];
	values = new VARIANT[count];
	quality = new WORD[count];
	//zzz check for errors...

	for(i=0; i<count; i++)
	{
		VariantInit(&values[i]);
	}

	// Figure out where the ITEM headers start
	// And also where the DATA starts
	// We will read the two areas in parallel
	//
	iptr = sptr + sizeof(OPCGROUPHEADER);
	dptr = iptr + (count * sizeof(OPCITEMHEADER2)); 

	// For each ITEM in the stream...
	//
	for(i=0; i<count; i++)
	{
		OPCITEMHEADER2 * item;

		// find the next item header
		//
		item = (OPCITEMHEADER2*)iptr;
		iptr += sizeof( OPCITEMHEADER2 );

		// Find the data for the item
		//
		dptr = sptr + item->dwValueOffset;

		// Copy the client handle and quality
		//
		handles[i] = item->hClient;
		quality[i] = item->wQuality;
		if(quality[i] != 0xc0) masterquality = 1;

		// And then the data (which is a bit trickey)
		//
		OPCVariantUnpack(&values[i], dptr);
	}

	// now do something with the data...
	// which we also has to free...
	//
	//zzz also need to sort out read complete vs data change
	// also what to do with hrStatus ?
	//
	OnDataChange(grp->dwTransactionID,
		grp->hClientGroup,
		count,
		handles,
		values,
		masterquality,
		quality,
		0);

	// Free all of the scratch variables
	//
	for(i=0; i<count; i++) VariantClear(&values[i]);

	if(handles) delete [] handles;
	if(values) delete [] values;
	if(quality) delete [] quality;

	return;
}

	
///////////////////////////////////////
// Handle Data Stream WITH TIMESTAMP...
// This code does NOT handle arrays
//
///////////////////////////////////////
void HandleDataTime(
	 STGMEDIUM *pSTM
)
{
	DWORD	count;
	OPCGROUPHEADER *grp;
	char *iptr;
	char *dptr;
	char *sptr;
	BOOL masterquality;
	unsigned int i;

	// Open the STGMEDIUM
	// and read the GROUP header
	//
	sptr = (char*)GlobalLock(pSTM->hGlobal);
	if(!sptr) return;

	grp = (OPCGROUPHEADER*)sptr;
	if(grp->hrStatus)
	{
		printf("\thrStatusr=%lx\n", grp->hrStatus);
		return;
	}

	// Allocate some memory into which to put the returned data
	//
	OPCHANDLE * handles;
	WORD      * quality;
	VARIANT   * values; 
	FILETIME  * ft;

	count = grp->dwItemCount;

	masterquality = 0;
	handles = new OPCHANDLE[count];
	values = new VARIANT[count];
	quality = new WORD[count];
	ft = new FILETIME[count];
	//zzz check for errors...

	for(i=0; i<count; i++)
	{
		VariantInit(&values[i]);
	}

	// Figure out where the ITEM headers start
	// And also where the DATA starts
	// We will read the two areas in parallel
	//
	iptr = sptr + sizeof(OPCGROUPHEADER);
	dptr = iptr + (count * sizeof(OPCITEMHEADER1)); 

	// For each ITEM in the stream...
	//
	for(i=0; i<count; i++)
	{
		OPCITEMHEADER1 * item;

		// find the next item header
		//
		item = (OPCITEMHEADER1*)iptr;
		iptr += sizeof( OPCITEMHEADER1 );

		// Find the data for the item
		//
		dptr = sptr + item->dwValueOffset;

		// Copy the client handle and quality
		//
		handles[i] = item->hClient;
		quality[i] = item->wQuality;
		ft[i] = item->ftTimeStampItem;
		if(quality[i] != 0xc0) masterquality = 1;

		// And then the data (which is a bit trickey)
		//
		OPCVariantUnpack(&values[i], dptr);
	}

	// now do something with the data...
	// which we also has to free...
	//
	//zzz also need to sort out read complete vs data change
	// also what to do with hrStatus ?
	//
	OnDataChange(grp->dwTransactionID,
		grp->hClientGroup,
		count,
		handles,
		values,
		masterquality,
		quality,
		ft);

	// Free all of the scratch variables
	//
	for(i=0; i<count; i++) 
	{
		VariantClear(&values[i]);
	}

	if(handles) delete [] handles;
	if(values) delete [] values;
	if(quality) delete [] quality;
	if(ft) delete [] ft;

	return;
}


///////////////////////////////////////
// Handle Data Stream for Write...
//
///////////////////////////////////////
void HandleWrite(
	 STGMEDIUM *pSTM
)
{
	DWORD	count;
	OPCGROUPHEADERWRITE *grp;
	char *iptr;
	char *sptr;
	BOOL masterhr;
	unsigned int i;

	// Open the STGMEDIUM
	// and read the GROUP header
	//
	sptr = (char*)GlobalLock(pSTM->hGlobal);
	if(!sptr) return;

	grp = (OPCGROUPHEADERWRITE*)sptr;
	if(grp->hrStatus)
	{
		printf("\thrStatusr=%lx\n", grp->hrStatus);
		return;
	}

	// Allocate some memory into which to put the returned data
	//
	OPCHANDLE * handles;
	HRESULT   * hrs;

	count = grp->dwItemCount;

	masterhr = 0;
	handles = new OPCHANDLE[count];
	hrs = new HRESULT[count];
	//zzz check for errors...

	// Figure out where the ITEM headers start
	//
	iptr = sptr + sizeof(OPCGROUPHEADERWRITE);

	// For each ITEM in the stream...
	//
	for(i=0; i<count; i++)
	{
		OPCITEMHEADERWRITE * item;

		// find the next item header
		//
		item = (OPCITEMHEADERWRITE*)iptr;
		iptr += sizeof( OPCITEMHEADERWRITE );

		// Copy the client handle and hresult
		//
		handles[i] = item->hClient;
		hrs[i] = item->dwError;
		if(hrs[i] != S_OK) masterhr = 1;
	}

	// now do something with the results...
	//
	OnWriteComplete(grp->dwTransactionID,
		grp->hClientGroup,
		count,
		handles,
		hrs,
		masterhr);

	// Free all of the scratch variables
	//

	if(handles) delete [] handles;
	if(hrs) delete [] hrs;

	return;
}

	

	





//---------------------------------------------------------
//
//
void OnDataChange(
	 DWORD       Transid, 
	 OPCHANDLE   grphandle, 
	 DWORD       count, 
	 OPCHANDLE * clienthandles, 
	 VARIANT   * value, 
	 BOOL        masterquality,
	 WORD      * quality,
	 FILETIME  * time
)
{
	unsigned int i;

	printf("OnDataChange: Transid=%ld count=%ld GrpHandle=%ld\n", Transid, count, grphandle);
	for(i=0; i<count; i++)
	{
		DumpValue(i, &value[i], quality[i], clienthandles[i]);
	}
	// Note we do NOT free memory here!
}


//---------------------------------------------------------
//
//
void OnWriteComplete(
	 DWORD       Transid, 
	 OPCHANDLE   grphandle, 
	 DWORD       count, 
	 OPCHANDLE * clienthandles, 
	 HRESULT   * hrs, 
	 BOOL        masterhr
)
{
	unsigned int i;

	printf("OnWriteComplete: Transid=%ld count=%ld GrpHandle=%ld\n", Transid, count, grphandle);
	for(i=0; i<count; i++)
	{
		printf("  [%d]-handle=%d, HR=%x\n", i, clienthandles[i], hrs[i]);
	}
	// Note we do NOT free memory here!
}


//---------------------------------------------------------
// DumpValue
// This shows the value of a Variant
static void	DumpValue(int i, VARIANT *v, WORD q, OPCHANDLE h)
{
	printf("  [%d]-handle=%d, Qual=%2x, ", i, h, q);
	DumpVariant(v);
	printf("\n");
}

⌨️ 快捷键说明

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