用VC6封装的OPCClient 库源代码,以及开发例程。
更多的OPC Server源代码例程下载:http://ishare.iask.sina.com.cn/f/24810582.html
extern "C"
{
// Class construct for OPCSink objects
//
OPCSINK_API COPCSinkObject* WINAPI CreateOPCSinkObject(void)
{
return ::new COPCSinkObjectImpl();
}
// Destroyer for OPCSink objects
//
OPCSINK_API long WINAPI DestroyOPCSinkObject(COPCSinkObject* pServer)
{
if( pServer != NULL ) {
::delete (COPCSinkObjectImpl *)pServer;
return 1;
}
return 0;
}
}
COPCSinkObjectImpl::COPCSinkObjectImpl(void)
{
// Initialize member variables:
m_pCurServer = NULL;
m_pCurGroup = NULL;
m_nListIndex = 0;
try
{
m_cItemList.SetSize (DEF_ITEM_LIST_SIZE, DEF_ITEM_LIST_SIZE);
}
catch (...)
{
ASSERT (FALSE);
}
m_pSinkDataInterface = NULL;
}
COPCSinkObjectImpl::~COPCSinkObjectImpl(void)
{
m_pSinkDataInterface = NULL;
StopServer();
RemoveAllTag();
}
/// Set server name ( e.g. "Kingso.OPCServer" )
void COPCSinkObjectImpl::SetOPCProgID(LPCTSTR lpszProgID)
{
m_oSinkSetting.SetOPCProgID( lpszProgID );
}
void COPCSinkObjectImpl::SetGroupName(LPCTSTR lpszGroupName)
{
m_oSinkSetting.SetGroupName( lpszGroupName );
}
void COPCSinkObjectImpl::SetTimeBase(DWORD dwTimeBase)
{
m_oSinkSetting.SetTimeBase( dwTimeBase );
}
void COPCSinkObjectImpl::SetUpdateRate(DWORD dwMinUpdateRate)
{
m_oSinkSetting.SetUpdateRate( dwMinUpdateRate );
}
/// Set the ProgID name and group param of sink ( e.g."XML string" )
void COPCSinkObjectImpl::SetOPCParam(LPCTSTR lpszXMLParam)
{
m_oSinkSetting.ConvertXML2Variant( lpszXMLParam );
}
HRESULT COPCSinkObjectImpl::SetCallbackObject( CSinkDataInterface * pDataInterface)
{
m_pSinkDataInterface = pDataInterface;
return S_OK;
}
/// To Initialize a sink
HRESULT COPCSinkObjectImpl::Initialize()
{
return S_OK;
}
/// To Uninitialize a sink
HRESULT COPCSinkObjectImpl::Uninitialize()
{
return S_OK;
}
/// To start a server
HRESULT COPCSinkObjectImpl::StartServer()
{
CSafeLock cs (&m_csSink);
if (OpenContents() == FALSE)
return E_FAIL;
AddTagItems();
return S_OK;
}
/// To stop process of a server
HRESULT COPCSinkObjectImpl::StopServer()
{
CSafeLock cs (&m_csSink);
DeleteContents();
return S_OK;
}
BOOL COPCSinkObjectImpl::IsOPCSinkAlive()
{
BOOL bALive = FALSE;
if (m_pCurServer)
bALive = m_pCurServer->IsAlive();
return bALive;
}
void COPCSinkObjectImpl::AddTag( DWORD dwTagID, LPCTSTR lpszTagName, VARTYPE varType, WORD wAccessRight)
{
CSafeLock cs (&m_csSink);
TagItem * pstTagItem = new TagItem;
m_mapTagItems【dwTagID】 = pstTagItem;
if (pstTagItem == NULL)
return ;
pstTagItem->dwTagID = dwTagID;
pstTagItem->strTagName = lpszTagName;
pstTagItem->varType = varType;
pstTagItem->wAccessRight = wAccessRight;
}
void COPCSinkObjectImpl::RemoveTag(DWORD dwTagID)
{
CSafeLock cs (&m_csSink);
if (m_pCurServer && m_pCurGroup)
{
TagItem_Map_Iter iter = m_mapTagItems.find( dwTagID );
if (iter != m_mapTagItems.end())
{
TagItem_Map_Iter delIter = iter;
delete (*iter).second;
(*iter).second = NULL;
m_mapTagItems.erase( delIter );
}
}
RemoveItemTag(dwTagID);
}
void COPCSinkObjectImpl::RemoveAllTag()
{
CSafeLock cs (&m_csSink);
if (m_mapTagItems.size() > 0)
{
TagItem_Map_Iter iter = m_mapTagItems.begin();
for( ; iter != m_mapTagItems.end(); )
{
TagItem_Map_Iter delIter = iter;
delete (*iter).second;
(*iter).second = NULL;
++iter;
m_mapTagItems.erase( delIter );
}
m_mapTagItems.clear();
}
}
void COPCSinkObjectImpl::WriteTag( DWORD dwTagID, LPCTSTR lpszTagName, VARTYPE varType, WORD wAccessRight, LPCTSTR lpszTagValue)
{
// Build and issue write request:
try
{
//declareobject arrays to contain list of items to write to and
// the values to be written, and related variables:
CKItem *pItem = NULL;
CObArray cItems;
CStringArray cValues;
DWORD cdwItems = 0;
// Construct an item and value list for this write operation:
cItems.SetSize (1);
cValues.SetSize (1);
// which item values have been set:
for (long i = 0; i < m_nListIndex; i++)
{
// Get pointer to next item in list:
pItem = (CKItem *) m_cItemList【i】;
if ((pItem->GetNameID() == dwTagID) || !_tcsicmp(pItem->GetItemName(), lpszTagName))
break;
}
if (pItem)
{
// Write value entered, so add item and value to list of
// items to request writes for:
cItems 【0】 = pItem;
// Add corresponding write value to value array:
cValues 【0】 = lpszTagValue;
// Increment the number of items to write to:
++cdwItems;
}
// Send the write request (as long as there is at least one write value):
if (cdwItems > 0)
{
GetCurrentGroup()->WriteAsync20 (cItems, cValues, cdwItems);
}
}
catch (...)
{
TRACE (_T(" WriteAsync20 - memory exception thrown\r\n"));
}
}
void COPCSinkObjectImpl::SetItemActive( DWORD dwTagID, BOOL bActive)
{
// Build and issue write request:
try
{
//declareobject arrays to contain list of items to write to and
// the values to be written, and related variables:
CKItem *pItem = NULL;
// which item values have been set:
for (long i = 0; i < m_nListIndex; i++)
{
// Get pointer to next item in list:
pItem = (CKItem *) m_cItemList【i】;
if ((pItem->GetNameID() == dwTagID))
break;
}
if (pItem)
{
// Add the items to the group:
GetCurrentGroup()->SetItemActiveState (pItem, bActive);
}
}
catch (...)
{
TRACE (_T(" SetActive - memory exception thrown\r\n"));
}
}
void COPCSinkObjectImpl::AddTagItems( )
{
if (!m_pCurGroup)
return ;
//WORD wAccessRight = bReadOnly ? OPC_READABLE : OPC_READABLE | OPC_WRITEABLE;
TagItem_Map_Iter iter = m_mapTagItems.begin();
for (; iter != m_mapTagItems.end(); ++iter)
{
TagItem * pstItemTag = (*iter).second;
DWORD dwTagID = (*iter).first;
if ( pstItemTag && dwTagID )
{
CKItem * pItem = NULL;
try
{
// Instantiate a new CKItem object:
pItem = new CKItem (m_pCurGroup);
m_cItemList.SetAtGrow (m_nListIndex++, pItem);
// Set its properties:
pItem->SetNameID(dwTagID);
pItem->SetItemName(pstItemTag->strTagName);
pItem->SetDataType(pstItemTag->varType);
pItem->SetAccessRights(pstItemTag->wAccessRight);
pItem->SetActive(TRUE);
pItem->SetAccessPath(_T(""));
}
catch (...)
{
// If problem, self-delete and re-throw exception:
delete this;
AfxThrowArchiveException (CArchiveException::generic);
}
}
}
// Add the item to our list:
if (m_nListIndex > 0)
m_pCurGroup->AddItems (m_cItemList, m_nListIndex);
}
void COPCSinkObjectImpl::SetCurrentServer(CKServer *pServer)
{
m_pCurServer = pServer;
}
CKServer* COPCSinkObjectImpl::GetCurrentServer()
{
return (m_pCurServer);
}
void COPCSinkObjectImpl::SetCurrentGroup(CKGroup *pGroup)
{
m_pCurGroup = pGroup;
}
CKGroup* COPCSinkObjectImpl::GetCurrentGroup()
{
return (m_pCurGroup);
}
/// To start a server
BOOL COPCSinkObjectImpl::OpenContents()
{
CKServer *pServer = NULL;
try
{
// Instantiate a new CKServer object:
pServer = new CKServer ();
m_pCurServer = pServer;
AddGroup();
pServer->Start();
}
catch (CMemoryException *e)
{
// If memory exception thrown,deleteexception object and return FALSE
// to indicate failure.
e->Delete ();
return (FALSE);
}
// If we make it here, all went OK, so return TRUE:
return (TRUE);
}
/// To stop process of a server
void COPCSinkObjectImpl::DeleteContents()
{
if (m_pCurServer)
{
// Shutdown the server:
m_pCurServer->Stop ();
//deleteserver (previously the head of linked list):
delete m_pCurServer;
// Invalidate currently selected server and group:
m_pCurServer = NULL;
m_pCurGroup = NULL;
m_nListIndex = 0;
}
}
// **************************************************************************
// AddGroup ()
//
// Description:
// Allows for the addition of a new group to a server item. The group will
// be attached the server‘s group list.
//
// Parameters:
// none
//
// Returns:
// void
// **************************************************************************
void COPCSinkObjectImpl::AddGroup ()
{
ASSERT (m_pCurServer != NULL);
CKGroup * pGroup = NULL;
try
{
// Instantiate a new CKGroup:
pGroup = new CKGroup (m_pCurServer);
}
catch (...)
{
// If problem,deletethe group and return with IDCANCEL code:
ASSERT (FALSE);
pGroup = NULL;
return;
}
pGroup->SetName (m_oSinkSetting.m_strOPCGroupName);
pGroup->SetActive (m_oSinkSetting.m_bActiveState);
pGroup->SetLanguageID (m_oSinkSetting.m_dwLanguageID);
pGroup->SetDeadband ((float)(m_oSinkSetting.m_nDeadband / 100.0));
pGroup->SetBias (m_oSinkSetting.m_dwTimeBase);
pGroup->SetUpdateRate (m_oSinkSetting.m_dwUpdateRate);
pGroup->SetUpdateMethod (m_oSinkSetting.m_nUpdateMethod);
// If this is a new group (indicated by non-NULL m_pServer),
// add it to the server:
if (m_pCurServer)
m_pCurServer->AddGroup (pGroup);
m_pCurGroup = pGroup;
pGroup->SetCallbackObject(m_pSinkDataInterface);
}
// **************************************************************************
// AddItem ()
//
// Description:
// Allows for the addition of a group‘s item(s).
//
// Parameters:
// CObArray &cList Object array of items to add.
// DWORD dwCount Number of items in cList.
//
// Returns:
// void
// **************************************************************************
void COPCSinkObjectImpl::AddItems (CObArray &cList, DWORD dwCount)
{
// Get the currently group:
CKGroup *pGroup = GetCurrentGroup ();
ASSERT (pGroup != NULL);
// Add the items to the group:
pGroup->AddItems (cList, dwCount);
}
// **************************************************************************
// RemoveItems ()
//
// Description:
// Allows for the removal of items on the selected group.
//
// Parameters:
// CObArray &cList Object array of items to remove.
// DWORD dwCount Number of items in cList.
//
// Returns:
// void
// **************************************************************************
void COPCSinkObjectImpl::RemoveItems (CObArray &cList, DWORD dwCount)
{
// Check that we specify a non-zero number of items (for debug only):
ASSERT (dwCount > 0);
// Get the currently selected group:
CKGroup *pGroup = GetCurrentGroup ();
ASSERT (pGroup != NULL);
// Remove the items from the group:
pGroup->RemoveItems (cList, dwCount);
}
void COPCSinkObjectImpl::RemoveItemTag(DWORD dwTagID)
{
if (m_pCurServer && m_pCurGroup)
{
CObArray cItemList;
cItemList.SetSize( 1 );
for (int i = 0; i < m_nListIndex; i++)
{
CKItem *pItem = NULL;
pItem = (CKItem *) m_cItemList【i】;
if (pItem->GetNameID() == dwTagID)
{
cItemList.SetAt (0, pItem);
RemoveItems(cItemList, 1);
m_cItemList.RemoveAt(i);
m_nListIndex--;
break;
}
}
}
}
楼主最近还看过