⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 privopc.h

📁 一个OPC服务器开发的源代码。结构清晰
💻 H
📖 第 1 页 / 共 2 页
字号:
/* IConnectionPoint methods */
 STDMETHOD (GetConnectionInterface)(IID *pIID);
 STDMETHOD (Advise)(IUnknown *pUnk, DWORD *pdwCookie);
 STDMETHOD (Unadvise)(DWORD dwCookie);
/* loConnPnt1 methods: */
 HRESULT icp_AddRef(void);
 void    icp_Release(void);
 loObjTracker *icp_ObjTracker(void);

/* IOPCServer implementation */
     STDMETHOD (GetErrorString)(HRESULT hr, LCID locale, LPWSTR *ppString);
     STDMETHOD (AddGroup)(LPCWSTR szName, BOOL bActive, DWORD dwRequestedUpdateRate,
		              OPCHANDLE hClientGroup, LONG *pTimeBias, FLOAT *pPercentDeadband,
		              DWORD dwLCID, OPCHANDLE *phServerGroup, DWORD *pRevisedUpdateRate,
		              REFIID riid, LPUNKNOWN *ppUnk);
     STDMETHOD (GetGroupByName)(LPCWSTR szGroupName, REFIID riid, LPUNKNOWN *ppUnk);
     STDMETHOD (GetStatus)(OPCSERVERSTATUS** ppServerStatus);
     STDMETHOD (RemoveGroup)(OPCHANDLE groupHandleID, BOOL bForce);
     STDMETHOD (CreateGroupEnumerator)(OPCENUMSCOPE dwScope, REFIID riid, LPUNKNOWN *ppUnk);

/* IOPCBrowseServerAddressSpace implementation */
     STDMETHOD (QueryOrganization)(OPCNAMESPACETYPE *pNameSpaceType);
     STDMETHOD (BrowseAccessPaths)(LPCWSTR szItemID, LPENUMSTRING *ppIEnumString);
     STDMETHOD (ChangeBrowsePosition)(OPCBROWSEDIRECTION dwBrowseDirection,
                                      LPCWSTR szString);
     STDMETHOD (GetItemID)(LPWSTR szItemDataID, LPWSTR *szItemID);
     STDMETHOD (BrowseOPCItemIDs)(OPCBROWSETYPE dwBrowseFilterType,
            /* [string][in] */ LPCWSTR szFilterCriteria,
            /* [in] */ VARTYPE vtDataTypeFilter,
            /* [in] */ DWORD dwAccessRightsFilter,
            /* [out] */ LPENUMSTRING *ppIEnumString);

/* IOPCItemProperties implementation */
     STDMETHOD (QueryAvailableProperties) (LPWSTR szItemID, DWORD* pwdCount, DWORD** ppPropertyIDs,
                                           LPWSTR **ppDescriptions, VARTYPE **ppvtDataTypes);

     STDMETHOD (GetItemProperties) (LPWSTR szItemID, DWORD dwCount, DWORD* pdwPropertyIDs,
 	                            VARIANT **ppvData, HRESULT **ppErrors);
     STDMETHOD (LookupItemIDs) (LPWSTR szItemID, DWORD dwCount, DWORD* pdwPropertyIDs,
		                LPWSTR **ppsNewItemIDs, HRESULT **ppErrors);
/***************************/
      HRESULT internalAddGroup(LightOPCGroup *grp,
			       LPCWSTR szName, BOOL bActive, DWORD UpdateRate,
			       OPCHANDLE hClientGroup, LONG *pTimeBias,
			       FLOAT *pPercentDeadband, DWORD dwLCID,
			       OPCHANDLE *phServerGroup,
			       REFIID riid, LPUNKNOWN *ppUnk);
      HRESULT internalRemoveGroup(unsigned groupHandleID, int bForce);
     int send_callback(LightOPCGroup *grp, unsigned group_key, loUpdList *upl, int advmask);
        /* unlocks previous lock! */
     LightOPCServer *iam;
};

class LightOPCGroup : public IOPCGroupStateMgt,
		      public IOPCPublicGroupStateMgt,
		      public IOPCItemMgt,
		      public IOPCSyncIO,
                      public IDataObject,
		      public IOPCAsyncIO,
		      public IOPCAsyncIO2,
                      public loConnPnt1
{
    LO_OBJ_XREF;
private:
    int iam_attached(void);
public:
/* Group basic properties & methods */
    unsigned long initphase;
    glGrowingList itl;

    LightOPCServer *owner;
    loWchar *name;

    OPCHANDLE ClientHandle;
    OPCHANDLE ServerHandle;
    loMilliSec UpdateRate;
    FLOAT Deadband;
    LCID  grLCID;
    LONG  TimeBias;

    loMilliSec LastUpdate;

    void /*IOPCDataCallback*/ *conn_databack;
    void /*IAdviseSink*/ *conn_dataonly, *conn_datatime, *conn_writecompl;
    int /*char*/ advise_present, advise_enabled; /* loRQ_CONN_*** */
    int /*BOOL*/ Active;
/* GetEnable() SetEnable() can modify advise_present because
   they are not work if connection was not advised.
   Thus advise_enabled can be eliminated
   but how we'll find connections for explicit Refresh/Read/Write ? */
    int /*BOOL*/ justactuated;
    unsigned active_count;
    loTrid last_trid;

    void clear_advise(void);

/*      lw_mutex lkValues; since Read() must (or must not?) affects
        OnDataChange() behavior we will not change last_sent
        value except from async_pipe */

	LightOPCGroup();
	virtual ~LightOPCGroup();
    inline int iam_valid(void) { return loIS_VALID(this); }
    void attach(LightOPCServer *);
    void detach(LightOPCServer *);
    void clear_all(void);
        int lock_state(const char *msg);
 inline void unlock_state(void)
{ lw_rw_unlock(&owner->lk_remove);
  owner->unlock_state();
// UL_DEBUG((LOGID, "Group:%u(%p) Leave.Ok", ServerHandle, this));
}

	inline void lock_read(void)  { owner->lock_read(); }
	inline void lock_write(void) { owner->lock_write(); }
	inline void unlock(void) { owner->unlock(); }

    inline HRESULT set_name(const loWchar *nname)
          { return loPWstrdup(&name, nname)? E_OUTOFMEMORY: S_OK; }

    void actuate_async(int justActuated);
        /* touch owner->async & set just_activated (clear lasttrid) */
        /* should be called from set_active() & XX_Advise() */

inline LightOPCItem *by_index(unsigned index)
      { return /*index >= 1 &&*/ index-1 < itl.gl_count?
                              (LightOPCItem*)itl.gl_list[index-1]: 0; }
inline unsigned add(LightOPCItem *item) { return gl_insert(&itl, item, 0); }
      int del(unsigned indx);
      void del_all(void);

/* loConnPnt1 methods: */
 HRESULT icp_AddRef(void);
 void    icp_Release(void);
 loObjTracker *icp_ObjTracker(void);

/* IUnknown implementation */
     LONG RefCount;
     STDMETHOD_ (ULONG, AddRef)(void);
     STDMETHOD_ (ULONG, Release)(void);
     STDMETHOD (QueryInterface) (REFIID riid, void **ppv);

     void set_active(BOOL); /* unlocked */
//inline int is_handle(OPCHANDLE hd)
//{ return (unsigned)hd >= 1 && (unsigned)(hd) <= count? S_OK: loOPC_E_INVALIDHANDLE; }

/* IOPCGroupStateMgt implementation */
    STDMETHOD (GetState)(DWORD *pUpdateRate, BOOL *pActive, LPWSTR *ppName,
		                  LONG *pTimeBias, FLOAT *pPercentDeadband, DWORD *pLCID,
		                  OPCHANDLE * phClientGroup, OPCHANDLE * phServerGroup);
    STDMETHOD (SetState)(DWORD *pRequestedUpdateRate, DWORD *pRevisedUpdateRate,
		                  BOOL *pActive, LONG *pTimeBias, FLOAT *pPercentDeadband,
		                  DWORD *pLCID, OPCHANDLE *phClientGroup);
    STDMETHOD (SetName) (LPCWSTR szName);
    STDMETHOD (CloneGroup)(LPCWSTR szName,	REFIID riid, LPUNKNOWN * ppUnk);

/* IOPCPublicGroupStateMgt implementation */
    STDMETHOD (GetState)(BOOL *pPublic);
    STDMETHOD (MoveToPublic)(void);

/* IOPCSyncIO implementation */
    STDMETHOD (Read)(OPCDATASOURCE dwSource, DWORD dwNumItems, OPCHANDLE *phServer,
		         OPCITEMSTATE **ppItemValues, HRESULT **ppErrors);
    STDMETHOD (Write)(DWORD dwNumItems, OPCHANDLE  * phServer, VARIANT *pItemValues,
		          HRESULT **ppErrors);

/* IOPCAsyncIO implementation */
    STDMETHOD (Read)(/* [in] */ DWORD dwConnection,
    		     /* [in] */ OPCDATASOURCE dwSource,
		     /* [in] */ DWORD dwCount,
		    /* [size_is][in] */ OPCHANDLE *phServer,
		    /* [out] */ DWORD __RPC_FAR *pTransactionID,
		    /* [size_is][size_is][out] */ HRESULT **ppErrors);
    STDMETHOD (Write)(/* [in] */ DWORD dwConnection,
            /* [in] */ DWORD dwCount,
            /* [size_is][in] */ OPCHANDLE *phServer,
            /* [size_is][in] */ VARIANT *pItemValues,
            /* [out] */ DWORD __RPC_FAR *pTransactionID,
            /* [size_is][size_is][out] */ HRESULT **ppErrors);
    STDMETHOD (Refresh)(/* [in] */ DWORD dwConnection,
            /* [in] */ OPCDATASOURCE dwSource,
            /* [out] */ DWORD *pTransactionID);
    STDMETHOD (Cancel)(/* [in] */ DWORD dwTransactionID);

/* IOPCAsyncIO2 implementation */
	STDMETHOD (Read) (DWORD dwCount, OPCHANDLE *phServer, DWORD dwTransactionID,
		          DWORD *pdwCancelID, HRESULT **pErrors);
	STDMETHOD (Write)(DWORD dwCount, OPCHANDLE *phServer, VARIANT *pItemValues,
		          DWORD dwTransactionID, DWORD *pdwCancelID, HRESULT **pErrors);
	STDMETHOD (Refresh2)(OPCDATASOURCE dwSource, DWORD dwTransactionID, DWORD *pdwCancelID);
	STDMETHOD (Cancel2)(DWORD pdwCancelID);
	STDMETHOD (SetEnable)(BOOL bEnable);
	STDMETHOD (GetEnable)(BOOL *pbEnable);

/* IOPCItemMgt implementation */
	STDMETHOD (AddItems)(DWORD dwNumItems, OPCITEMDEF *pItemArray, OPCITEMRESULT **ppAddResults,
		             HRESULT **ppErrors);
	STDMETHOD (ValidateItems)(DWORD dwNumItems, OPCITEMDEF *pItemArray,	BOOL bBlobUpdate,
		                  OPCITEMRESULT **ppValidationResults, HRESULT **ppErrors);
	STDMETHOD (RemoveItems)(DWORD dwNumItems, OPCHANDLE  * phServer, HRESULT **ppErrors);
	STDMETHOD (SetActiveState)(DWORD dwNumItems, OPCHANDLE *phServer, BOOL bActive,
		                   HRESULT **ppErrors);
	STDMETHOD (SetClientHandles)(DWORD dwNumItems, OPCHANDLE *phServer, OPCHANDLE *phClient,
		                     HRESULT **ppErrors);
	STDMETHOD (SetDatatypes)(DWORD dwNumItems, OPCHANDLE *phServer, VARTYPE *pRequestedDatatypes,
		                 HRESULT **ppErrors);
 	STDMETHOD (CreateEnumerator)(REFIID riid, LPUNKNOWN *ppUnk);

/* IDataObject implementation */
        STDMETHOD (GetData)(FORMATETC *pformatetcIn, STGMEDIUM *pmedium);
        STDMETHOD (GetDataHere)(FORMATETC *pformatetc, STGMEDIUM *pmedium);
        STDMETHOD (QueryGetData)(FORMATETC *pformatetc);
        STDMETHOD (GetCanonicalFormatEtc)(FORMATETC *pformatectIn, FORMATETC *pformatetcOut);
        STDMETHOD (SetData)(FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease);
        STDMETHOD (EnumFormatEtc)(DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc);
        STDMETHOD (DAdvise)(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink,
                            DWORD *pdwConnection);
        STDMETHOD (DUnadvise)(DWORD dwConnection);
        STDMETHOD (EnumDAdvise)(IEnumSTATDATA **ppenumAdvise);

/* IConnectionPoint methods */
 STDMETHOD (GetConnectionInterface)(IID *pIID);
 STDMETHOD (Advise)(IUnknown *pUnk, DWORD *pdwCookie);
 STDMETHOD (Unadvise)(DWORD dwCookie);

/************************************************************************/

  HRESULT internalValidateItems(DWORD dwCount,
                                OPCITEMDEF *idefs,
                                loTagId *tid, void **acpath,
		                        OPCITEMRESULT **iresults,
                                HRESULT **ppErrors);

        LightOPCGroup *iam;
};


class LightOPCItem
{
     LO_OBJ_XREF;
public:
    loWchar *szItemID;
    loWchar *szAccessPath;
    BOOL bActive;
    OPCHANDLE hClient;
    VARTYPE vtRequestedDataType;
/* note: Changing from inactive to active should cause OnDataChange()
   thus: the quality or the value of last_sent must be updated together bActive */

    loTagId tid;
    loCONV  convtype;
    unsigned *lastsent;
    double   numeric;
    loTrid   last_changed;
 inline void TouchChanged(void) {
#if 0
                                 last_changed = 0;
#endif
                                }
    int      Quality; /* -1 is used as an unusable quality */
    void    *AcPath;

    LightOPCItem();
    virtual ~LightOPCItem ();

    void attach(void *);
    void detach(void *);
    inline HRESULT set_accpath(const loWchar *newpath)
          { return loPWstrdup(&szAccessPath, newpath)? E_OUTOFMEMORY: S_OK; };
    inline HRESULT set_itemid(const loWchar *itemid)
          { return loPWstrdup(&szItemID, itemid)? E_OUTOFMEMORY: S_OK; }
};

unsigned lo_refresh_items(loService *se, loUpdList *upl, LightOPCGroup *grp);
int lo_OnDataChange1(loUpdList *upl, OPCHANDLE hClient, unsigned cform,
                     int with_time, IAdviseSink *ias, HGLOBAL *gmem, unsigned *hint_dsize);
int lo_OnWriteComplete1(loUpdList *upl, OPCHANDLE hClient, unsigned cform,
                        IAdviseSink *ias, HGLOBAL *gmem);
int lo_rio_requests(LightOPCServer *cli);

#endif /*__cplusplus*/
/*********************  end of privopc.h *********************************/
#endif /* PRIVOPC_H */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -