在vs2008中读取OPC数据 出现内存无法访问的问题

whwqyu 2016-10-26 02:03:39
参考http://blog.csdn.net/yuanhaosh/article/details/40614859这篇文章,改写了程序,使用定时器周期性读取opc数据,但是在关闭程序时IOPCSyncIO->Read总是会报错
...全文
643 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
whwqyu 2016-10-26
  • 打赏
  • 举报
回复
使用的西门子s7-300 关键代码
BOOL COPCDEMODlg::InitOPCServer()
{
    CLSID clsid;
	HRESULT hr = S_OK;
	CString strServer = "OPC.SimaticNET";  //OPC.SimaticNET S7200.OPCServer

	/*初始化COM库*/
	if (FAILED(::CoInitialize(NULL))) 
	{
		AfxMessageBox("Error during CoInitialize", MB_OK );
        return FALSE;
	}
	
	/*查找OPC服务*/
	hr = CLSIDFromProgID(strServer.AllocSysString(), &clsid );
	if( FAILED(hr))
	{
        AfxMessageBox("Error during CLSIDFromProgID", MB_OK);
        return FALSE;
	}
	
	/*创建OPC服务器对象*/
	LPUNKNOWN pUnkn = NULL;  
	hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER , IID_IOPCServer, (void**)&m_IOPCServer); //CLSCTX_LOCAL_SERVER CLSCTX_ALL
	if( FAILED(hr) || m_IOPCServer == NULL)
	{
        AfxMessageBox("Error during CoCreateInstance", MB_OK);
        return FALSE;
	}

	/*添加组到OPC服务器*/
	FLOAT PercentDeadband = 0.0;
	DWORD RevisedUpdateRate;

	hr = m_IOPCServer->AddGroup(
		L"group",                 //[in]  组名
        TRUE,                    //[in]  活动状态
        500,                     //[in]  向服务器发送请求的刷新率
        1,                       //[in]  客户端的操作句柄
        NULL,                    //[in]  与标准时间的校正值
        &PercentDeadband,        //[in]  要舍弃的数据	
        0,                       //[in]  服务器使用的语言
        &m_GrpSrvHandle,         //[out] 添加组以后服务器返回的组句柄
        &RevisedUpdateRate,      //[out] 服务器的数据刷新率  
        IID_IOPCItemMgt,         //[in]  添加组的接口类型
        (LPUNKNOWN*)&m_IOPCItemMgt);  //[out] 服务器返回的接口对象指针
	if( FAILED(hr) )
	{  
		LPWSTR pErrString;
        AfxMessageBox("Error during AddGroup", MB_OK);
		hr = m_IOPCServer->GetErrorString(hr, LOCALE_SYSTEM_DEFAULT, &pErrString);
		if(SUCCEEDED(hr))
		{
			//输出错误信息
		}
		else
		{
			//pErrString = "添加组失败.";
		}
		m_IOPCServer->Release();
		m_IOPCServer=NULL;
		CoUninitialize();
        return FALSE;
	}
	
	CString TableStr[COUNT]= {"NewItem"};
//	OPCITEMDEF *m_Items = new OPCITEMDEF[COUNT];                   //项的存取路径, 定义和被请求的数据类等
	
	m_Items[0].szItemID = L"S7:[S7 connection_1]DB300,REAL0"; //油温
	m_Items[0].dwBlobSize = 0;
	m_Items[0].pBlob = NULL;
	m_Items[0].bActive = TRUE;
	m_Items[0].hClient = (OPCHANDLE)1;
	m_Items[0].szAccessPath = L"";  
	m_Items[0].vtRequestedDataType = VT_EMPTY;                      

	m_Items[1].szItemID = L"S7:[S7 connection_1]DB300,REAL4"; //压差
	m_Items[1].dwBlobSize = 0;
	m_Items[1].pBlob = NULL;
	m_Items[1].bActive = TRUE;
	m_Items[1].hClient = (OPCHANDLE)2;
	m_Items[1].szAccessPath = L"";  
	m_Items[1].vtRequestedDataType = VT_EMPTY;  

	m_Items[2].szItemID = L"S7:[S7 connection_1]DB300,REAL8"; //大流量
	m_Items[2].dwBlobSize = 0;
	m_Items[2].pBlob = NULL;
	m_Items[2].bActive = TRUE;
	m_Items[2].hClient = (OPCHANDLE)3;
	m_Items[2].szAccessPath = L"";  
	m_Items[2].vtRequestedDataType = VT_EMPTY;  

	/*添加项目*/ 
    OPCITEMRESULT *pOPCResults = NULL;
	HRESULT *pOPCErrors = NULL;
    hr = m_IOPCItemMgt->AddItems(COUNT, 
		m_Items,
		&pOPCResults, 
		&pOPCErrors);
	if(FAILED(hr))
	{
		LPWSTR pErrString;
        AfxMessageBox("Error during AddGroup", MB_OK);
		hr = m_IOPCServer->GetErrorString(hr, LOCALE_SYSTEM_DEFAULT, &pErrString);
		if(SUCCEEDED(hr))
		{
			
			//输出错误信息
		}
		else
		{
			//pErrString = "添加组失败.";
		}
		m_IOPCServer->Release();
		m_IOPCServer=NULL;
		CoUninitialize();
        return FALSE;
	}
	AfxMessageBox("添加项目成功.");
	
	/*保存item对应的服务句柄*/
	pdwServerHandles = new DWORD[COUNT];
	for(int i = 0; i < COUNT; i++)
	{
		pdwServerHandles[i] = pOPCResults[i].hServer;
        if(pOPCErrors[i]= S_OK)
		{
			pdwServerHandles[i] = pOPCResults[i].hServer;  
		}
	}

	/*获取同步IO口*/
	hr = m_IOPCItemMgt->QueryInterface(IID_IOPCSyncIO, (void**)&m_IOPCSyncIO);
    if(FAILED(hr))
	{
		LPWSTR pErrString;
        AfxMessageBox("获取IO口失败", MB_OK);
		hr = m_IOPCServer->GetErrorString(hr, LOCALE_SYSTEM_DEFAULT, &pErrString);
		if(SUCCEEDED(hr))
		{
			
			//输出错误信息
		}
		else
		{
			//pErrString = "获取IO口失败.";
		}
		m_IOPCServer->Release();
		m_IOPCServer=NULL;
		CoUninitialize();
        return FALSE;
	}

// delete[] pdwServerHandles;
//	delete[] m_Items;
//	delete pcItem;
	return TRUE; 	//初始化完成,可以开始查询.
}

void COPCDEMODlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	HRESULT hr = S_OK;
	LPWSTR pErrString; //记录错误信息字符串

	try 
	{
		hr = m_IOPCSyncIO->Read(
			OPC_DS_CACHE,          // OPC_DS_CACHE, Source (device or cache)
			COUNT,//cdwItems,      	    // Item count
			pdwServerHandles,	// Array of server handles for items
			&pValues,	            // Array of values
			&pErrors);	            // Array of errors

		m_temprature=pValues[0].vDataValue.fltVal;
		m_bar=pValues[1].vDataValue.fltVal;
		m_flue=pValues[2].vDataValue.fltVal;
		UpdateData(false);

		if(FAILED(hr))
	    {	    
            AfxMessageBox("Error during ReadOPC", MB_OK);
		    hr = m_IOPCServer->GetErrorString(hr, LOCALE_SYSTEM_DEFAULT, &pErrString);
		    if(SUCCEEDED(hr))
		    {
			    //pErrString输出错误信息
		    }
		    else
		    {
			    //pErrString = "添加组失败.";
		    }
		    m_IOPCServer->Release();
		    m_IOPCServer=NULL;
		    CoUninitialize();
	    }

		
	}
	catch(...)
	{
	
	} 
	//	delete pValues;
	CDialog::OnTimer(nIDEvent);
}
whwqyu 2016-10-26
  • 打赏
  • 举报
回复

7,540

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 VC.NET
社区管理员
  • VC.NET社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧