【问题标题】:Error: WTclient - Failed to Execute OPCENUM错误:WTclient - 无法执行 OPCENUM
【发布时间】:2015-01-19 17:11:48
【问题描述】:

我正在编写一个 OPC 客户端来获取标签并将其发送到 OPC 服务器,但我遇到了这个错误: WTclient - 无法执行 OPCENUM 我的代码非常简单,我正在关注我在互联网上找到的一个完美运行的示例应用程序。 我的程序完美编译并运行,但是当达到 Numbr = NumberOfOPCServers(TRUE, MachineName);弹出错误的行。

我的 .ccp 是:

#include "stdafx.h"
#include "opcda.h"
#include "opc_ae.h"
#include "wtclientapi.h"
#include "OPC2.h"

int _tmain(int argc, _TCHAR* argv[])
{
    int Numbr;
    MachineName = "";
    Numbr = NumberOfOPCServers(TRUE, MachineName);
    return 0;
}

深入调试另一个互联网示例,我发现错误来自这个函数:

int CWTclientApp::GetServerListFromOPCENUM(CString pathname)
{
    IOPCServerList *gpOPC;
    HRESULT hr, hr2;
    IEnumGUID *pEnumGUID;
    CLSID catid, clsid;
    unsigned long c;
    LPOLESTR pszProgID, pszUserType;
    int i;
    OPCSVRDESCR *pSvr;

    for (i=0; i<MyServerList.GetSize(); i++)
        {
        pSvr = (OPCSVRDESCR *)MyServerList.GetAt(i);
        delete (pSvr);
        }
    MyServerList.RemoveAll();

    // create the enumerator object
    gpOPC = CreateServerEnumerator(pathname);
    if (gpOPC == NULL)
        {
        DoErrorMsg ( 0, "Failed to Execute OPCENUM");
        // revert to search of Registry if OPCENUM fails to execute
        return (GetServerListFromRegistry());
        }
............................................

从函数 NumberOfOPCServers() 中调用:

_declspec(dllexport) int  WINAPI NumberOfOPCServers (bool UseOPCENUM, LPCSTR MachineName)
{
    CWTclientApp    *pApp;
    CString path;

    path = MachineName;
    path.MakeUpper();
    if (path == "LOCAL")
        path = "";
    else
        path = MachineName;
    pApp = (CWTclientApp *)AfxGetApp();
    if (UseOPCENUM)
        return (pApp->GetServerListFromOPCENUM(path));
    else 
        return (pApp->GetServerListFromRegistry());
}

任何想法为什么我有这个错误?看起来 OPCenum.exe 没有枚举我的机器(本地服务器)上运行的 OPC 服务器,但为什么呢? (下载的应用可以,我的不行)

谢谢!!!!

编辑 ---------------------------------- -------------------------- CreateServerEnumerator():

IOPCServerList *CWTclientApp::CreateServerEnumerator (CString   PathName)
{
    HRESULT r2;
    MULTI_QI mqi;
    COSERVERINFO    sin, *sinptr;
    DWORD clsctx;

    // set up server info
    //
    if (PathName.GetLength() > 0)
        {
        sinptr = &sin;
        sin.dwReserved1 = 0;
        sin.dwReserved2 = 0;
        sin.pwszName = WSTRFromCString (PathName, FALSE);
        sin.pAuthInfo = 0;
        clsctx = CLSCTX_REMOTE_SERVER;
        } 
    else
        {
        sinptr = 0;     // pointer should be NULL if local
        clsctx = CLSCTX_LOCAL_SERVER;
        }

    // set up mqi
    //
    mqi.pIID = &IID_IOPCServerList;
    mqi.hr = 0;
    mqi.pItf = 0;    

    r2 = CoCreateInstanceEx(CLSID_OPCServerList, NULL, 
        clsctx, sinptr, 1, &mqi);    
    if (PathName.GetLength() > 0)
        WSTRFree (sin.pwszName, FALSE);    
    if (FAILED(r2) || FAILED(mqi.hr))
        return (NULL);    
    return (IOPCServerList*)mqi.pItf;
}

【问题讨论】:

  • 你有 CreateServerEnumerator 的源代码吗?
  • @ZbynekZ ,是的,问题已编辑。
  • r2 value --> r2 = 0x800401f0 : CoInitialize 没有被调用。

标签: c++ opc


【解决方案1】:

在调用任何其他 COM 函数之前,只需在使用 COM (OPC Classic) 的每个线程中调用 CoInitialize (https://msdn.microsoft.com/en-us/library/windows/desktop/ms678543(v=vs.85).aspx) 或 CoInitializeEx (https://msdn.microsoft.com/en-us/library/windows/desktop/ms695279(v=vs.85).aspx)。

CoInitialize 已过时,因此您应该使用 CoInitializeEx。

Microsoft 在他们的文档中对这个函数说:“对于使用 COM 库的每个线程,CoInitializeEx 必须至少调用一次,并且通常只调用一次”。

【讨论】:

  • 感谢您的回答。有用!。我刚刚调用了 WTclientCoInit();在代码的开头和 WTclientCoUninit();最后。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-17
  • 1970-01-01
  • 1970-01-01
  • 2014-08-29
  • 2014-01-27
相关资源
最近更新 更多