📄 opc_data.cpp
字号:
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 + -