VC++与OPC(pc access)通讯
最近做上位机开发,需要与PLC 通讯 。以前不知道以为要与PLC程序配合写 通讯 程序,后来联系西门子客服才知道这个问题早被解决了。网上《OPC_client_在VC环境下编程.doc》比较适合我(适合你的是最好的),表示感谢作者。在这篇的基础上我添加了一下自己的东
最近做上位机开发,需要与PLC通讯。以前不知道以为要与PLC程序配合写通讯程序,后来联系西门子客服才知道这个问题早被解决了。网上《OPC_client_在VC环境下编程.doc》比较适合我(适合你的是最好的),表示感谢作者。在这篇的基础上我添加了一下自己的东西。具体的Demo在http://download.csdn.net/detail/yuanhaosh/8098867下载
在这之前需要添加几个OPC相关的文件 opccomn_i.c ,opccomn.h, opcda.h, opcda_i.c, opcerror.h,已经包含在demo中了
这部分是初始化OPC的部分。
BOOL COPCDEMODlg::InitOPCServer()
{
CLSID clsid;
HRESULT hr = S_OK;
CString strServer = "S7200.OPCServer"; //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
{
//添加组失败;
}
m_IOPCServer->Release();
m_IOPCServer=NULL;
CoUninitialize();
return FALSE;
}
Item* pcItem ;
OPCITEMDEF *m_Items = new OPCITEMDEF[COUNT]; //项的存取路径, 定义和被请求的数据类等
for(int i = 0; i
{
pcItem = new Item;
pcItem->quality = QUAL_BAD;
//pcItem->name = _T("" + TableStr[i]); //设置opc节点 Microwin.NewPLC.group.
pcItem->name = _T("Microwin.NewPLC.group.NewItem1"); //这里的字符串填写你的item就行
m_Items[i].szItemID = pcItem->name.AllocSysString();
m_Items[i].dwBlobSize = 0;
m_Items[i].pBlob = NULL;
m_Items[i].bActive = TRUE;
m_Items[i].hClient = (OPCHANDLE)pcItem;
m_Items[i].szAccessPath = pcItem->cAccessPath.AllocSysString();; //pcItem->cAccessPath.AllocSysString();
m_Items[i].vtRequestedDataType = VT_EMPTY; //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;
}
/*保存item对应的服务句柄*/
pdwServerHandles = new DWORD[COUNT];
for(i = 0; 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; //初始化完成,可以开始查询.
}
/**************************************************************************************************
* 读取OPC服务器中的状态信息
* phServe: 读取项的句柄
* dwSource: 状态获取来源,缓存、内存
***************************************************************************************************
*/
BOOL COPCDEMODlg::ReadOPCServe(OPCITEMSTATE **pValues, OPCHANDLE *phServe, OPCDATASOURCE dwSource)
{
HRESULT hr = S_OK;
OPCHANDLE *phserve = phServe;
LPWSTR pErrString; //记录错误信息字符串
HRESULT *pErrors= new HRESULT;
try
{
hr = m_IOPCSyncIO->Read(
dwSource, // OPC_DS_CACHE, Source (device or cache)
1,
// Item count
(OPCHANDLE*)phServe,// Array of server handles for items
pValues,
// Array of values
&pErrors);
// Array of errors
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();
return FALSE;
}
}
catch(...)
{
}
//delete pErrors; 会出现异常报错请使用者再次检查原因,防止内存泄露
return TRUE;
}
/*****************************************************************************************
* 写入OPC服务器中的状态信息
* 后续需要再写 OPCITEMSTATE **pValues, OPCHANDLE *phServe, OPCDATASOURCE dwSource
******************************************************************************************/
BOOL COPCDEMODlg::WriteOPCServe(OPCHANDLE *phServe, BYTE Values)
{
HRESULT hr = S_OK;
VARIANT *pItemValues = new VARIANT;
OPCHANDLE *phserve = phServe;
HRESULT *pErrors= new HRESULT;
LPWSTR pErrString;
VariantClear(pItemValues);
memset(pItemValues, 0, sizeof(VARIANT));
pItemValues->vt = VT_I2;
short value = Values;
pItemValues->bVal = value;
try
{
hr = m_IOPCSyncIO->Write(1,
phserve,
pItemValues,
&pErrors);
if(FAILED(hr))
{
hr = m_IOPCServer->GetErrorString(hr, LOCALE_SYSTEM_DEFAULT, &pErrString);
if(SUCCEEDED(hr))
{
//pErrString输出错误信息
}
else
{
//pErrString = "写入失败.";
}
m_IOPCServer->Release();
m_IOPCServer=NULL;
CoUninitialize();
return FALSE;
}
}
catch(...)
{}
//delete pErrors; 会出现异常报错请使用者再次检查原因,防止内存泄露
return TRUE;
}

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











1. Windows 11で設定を開きます。 Win+I ショートカットまたはその他の方法を使用できます。 2. 「アプリ」セクションに移動し、「アプリと機能」をクリックします。 3. バックグラウンドでの実行を禁止したいアプリケーションを見つけます。三点ボタンをクリックして、[詳細オプション] を選択します。 4. [バックグラウンド アプリケーションのアクセス許可] セクションを見つけて、目的の値を選択します。デフォルトでは、Windows 11 は電力最適化モードを設定します。これにより、Windows はアプリケーションがバックグラウンドでどのように動作するかを管理できるようになります。たとえば、バッテリーを節約するためにバッテリー セーバー モードを有効にすると、システムはすべてのアプリを自動的に終了します。 5. アプリケーションがバックグラウンドで実行されないようにするには、[なし] を選択します。プログラムが通知を送信していない、データの更新に失敗しているなどに気付いた場合は、次のことができることに注意してください。

この AI 支援プログラミング ツールは、急速な AI 開発のこの段階において、多数の有用な AI 支援プログラミング ツールを発掘しました。 AI 支援プログラミング ツールは、開発効率を向上させ、コードの品質を向上させ、バグ率を減らすことができます。これらは、現代のソフトウェア開発プロセスにおける重要なアシスタントです。今日は Dayao が 4 つの AI 支援プログラミング ツールを紹介します (すべて C# 言語をサポートしています)。皆さんのお役に立てれば幸いです。 https://github.com/YSGStudyHards/DotNetGuide1.GitHubCopilotGitHubCopilot は、より少ない労力でより迅速にコードを作成できるようにする AI コーディング アシスタントであり、問題解決とコラボレーションにより集中できるようになります。ギット

DeepSeekはファイルを直接PDFに変換できません。ファイルの種類に応じて、異なる方法を使用できます。一般的なドキュメント(Word、Excel、PowerPoint):Microsoft Office、Libreoffice、その他のソフトウェアを使用してPDFとしてエクスポートします。画像:画像ビューアまたは画像処理ソフトウェアを使用してPDFとして保存します。 Webページ:ブラウザの「Print into PDF」関数を使用するか、PDFツールに専用のWebページを使用します。 UNCOMMONフォーマット:適切なコンバーターを見つけて、PDFに変換します。適切なツールを選択し、実際の状況に基づいて計画を作成することが重要です。

Java の DAO (Data Access Object) は、アプリケーション コードと永続層を分離するために使用されます。その利点は次のとおりです。 分離: アプリケーション ロジックから独立しているため、変更が容易になります。カプセル化: データベース アクセスの詳細を非表示にし、データベースとの対話を簡素化します。スケーラビリティ: 新しいデータベースや永続化テクノロジをサポートするために簡単に拡張できます。 DAO を使用すると、アプリケーションはデータベースの詳細を直接処理することなく、メソッドを呼び出してエンティティの作成、読み取り、更新、削除などのデータベース操作を実行できます。

アプリを使用しようとすると、「カメラとマイクへのアクセスを許可できません」というメッセージが表示されますか?通常、カメラとマイクのアクセス許可は、必要に応じて特定の人に付与します。ただし、許可を拒否すると、カメラとマイクは機能しなくなり、代わりにこのエラー メッセージが表示されます。この問題の解決は非常に基本的なもので、1 ~ 2 分で解決できます。解決策 1 – カメラ、マイクの権限を提供する 必要なカメラとマイクの権限を設定で直接提供できます。ステップ 1 – [設定] タブに移動します。ステップ 2 – [プライバシーとセキュリティ] パネルを開きます。ステップ 3 – そこで「カメラ」権限をオンにします。ステップ 4 – 内部には、携帯電話のカメラの許可を要求したアプリのリストが表示されます。ステップ5 – 指定したアプリの「カメラ」を開きます

Java では、「フィールド」は、データまたは状態を格納するために使用されるクラスまたはインターフェイスのデータ メンバーです。フィールドのプロパティには、タイプ (任意の Java データ型)、アクセス権、静的 (インスタンスではなくクラスに属する)、最終 (不変)、および一時 (シリアル化されていない) が含まれます。フィールドは、オブジェクト データの保存やオブジェクトの状態の維持など、クラスまたはインターフェイスの状態情報を保存するために使用されます。

Java リフレクション メカニズムを使用すると、プログラムはソース コードを変更せずにクラスの動作を動的に変更できます。 Class オブジェクトを操作することで、newInstance() によるインスタンスの作成、プライベート フィールドの値の変更、プライベート メソッドの呼び出しなどが可能になります。ただし、リフレクションは予期しない動作やセキュリティ上の問題を引き起こす可能性があり、パフォーマンスのオーバーヘッドがあるため、注意して使用する必要があります。

Vue で iframe クロスドメインの問題を解決する方法: CORS: バックエンド サーバーで CORS サポートを有効にし、XMLHttpRequest またはフェッチ API を使用して Vue で CORS リクエストを送信します。 JSONP: バックエンド サーバーの JSONP エンドポイントを使用して、Vue に JSONP スクリプトを動的に読み込みます。プロキシ サーバー: リクエストを転送するためにプロキシ サーバーを設定し、Vue のサードパーティ ライブラリ (axios など) を使用してリクエストを送信し、プロキシ サーバー URL を設定します。
