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

📄 lightopc.h

📁 OPCSERVER源代码
💻 H
📖 第 1 页 / 共 3 页
字号:
/**************************************************************************
 *                                                                        *
 * Light OPC Server development library                                   *
 *                                                                        *
 *   Copyright (c)  Timofei Bondarenko 2000-2002,                         *
 *   Copyright (c)  Kostya Volovich  2000                                 *
 **************************************************************************/

#ifndef LIGHTOPC_H
#define LIGHTOPC_H (0x0888)

#ifndef WINAPI
#include <windows.h>
#endif
/**************************************************************************
 General architecture
 ~~~~~~~~~~~~~~~~~~~~
 .......................................
 :            OPC Server               :
 :  ______                 _________   :             ___________
 : /      \               /         \  :            /           \
  / CUSTOM \             / Light-OPC \   OLE-COM   /             \
 <  DRIVER  >  lo-API   <   LIBRARY   >   OPC-DA  < An OPC-Client >
  \        /  interface  \           /  interface  \    (SCADA)  /
 : \______/               \_________/  :            \___________/
 :                                     :
 :.....................................:


 Data path
 ~~~~~~~~~
  _________                                ........................
 |         |                               :   _________________  :
 | Process |---------\  loCacheUpdate() ----->|                 | :
 |         |  DRIVER  >                    :  |    Secondary    | :
 |  Data   |-----^---/  loCacheLock() ------->|      Cache      | :
 |_________|     |                         :  |_________________| :
                 |     ______________      :    |             |   :
                 +----| ldReadTags() |     :    |             |   :
                      | ldWriteTags()|     :   \|loUpdatePipe |/  :
                      |______________|     :    \   thread    /   :
                            |              :     \           /    :
                            |              :   ___\_________/___  :
                       _____^____          :  |                 | :
    /=============  __|          | /----------|     Primary     | :
   /             __|  | loClient |<           |      Cache      | :
  <  OPC DA     |  |  |__________| \----------|_________________| :
   \            |  |__________|            :                      :
    \========== |___________|              :...... loService .....:


 Async. model
 ~~~~~~~~~~~~

 ... OPC-DA ..... ...loClient::client_scheduler() thread...      .. D ..
                 :                  ___________           :      :  R  :
      ___        :                 |           |/--/ UpdatePipe /=  I  :
     |   <--------- Subscription --|  Primary  |\--\~~ thread ~~\=  V  :
     |   <--------- OnDataChange --|   Cache   |<===+     :......:  E  :
     |           :                 |_____^_____|    |            :  R  :
     |   <-------------------------------|-------------Async--+  :     :
     |           :                       |          |         |  :     :
     |        +---------------+        CACHE        |         |  :     :
 AsyncIO ---->| Request Queue |          |          |    _____|__:____ :
              | q_req         |-- Async--+--DEVICE----->|             |:
              |               |                     |   | ldWriteTags |:
    DEVICE -->+---------------+-- Sync-DEVICE --------->| ldReadTags  |:
        |        :                                  |   |_____________|:
        |     +---------------+                     |         |  :     :
 SyncIO-+ <---| Response Queue|                     |         |  :     :
        |     | q_ret         |<------------------------Sync--+  :     :
        |     +---------------+                     |            :     :
     CACHE <========================================+            :     :
                 :...............................................:.....:

 **************************************************************************/
/** The <lo-API> is mostly described here. **/
/**************************************************************************

 Almost all functions are thread-safe except object destruction procedures.
 Naturally, once destruction initiated no one may use that object.

 **************************************************************************
 Public definitions to be exported:
 **************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif

#ifndef LO_PUBLIC
#define LO_PUBLIC /*extern*/
#endif

LO_PUBLIC
int loServerRegister(const GUID *CLSID_Svr, const char *ProgID,
    		         const char *ServName, const char *exPath,
                     const char *Model /* 0=exe, ""=STA dll, "Both", "Free" ...*/);
LO_PUBLIC
int loServerUnregister(const GUID *CLSID_Svr, const char *ProgID);
/* Returns 0: OK; != 0 on Failure, 
   GetLastError() will return error code.
   The exPath can be NULL or "" for an NT-Service. */

/*struct loService;*/
typedef struct loService loService;
/*struct loRealTag_;*/
typedef struct loRealTag_ *loRealTag;
#ifdef __cplusplus
class LightOPCServer;
typedef LightOPCServer loClient;
#else
struct LightOPCServer;
typedef struct LightOPCServer loClient;
#endif

#if 0
typedef loTagDesc *loTagId;
#else
typedef unsigned   loTagId;
#endif
/* 0 is UNEXISTING TagId / RealTag */

typedef unsigned loTrid; /* Transaction identifier for loUpdateCache */

typedef unsigned loPLid; /* Identifier of a proprties' list */
/* 0 is UNEXISTING list */

#if 1
typedef WCHAR   loWchar;
#else
typedef wchar_t loWchar;
#endif

typedef unsigned long loMilliSec; /* must be unsigned */

typedef struct loCaller /* Caller's context for ldCallbacks */
   {
    loService *ca_se;
    void *ca_se_arg;   /* a copy of loDriver::ldFirstArg */
    loClient  *ca_cli; /* can be NULL if no loClient assotiated with request */
    void *ca_cli_arg;  /* a copy of loClientCreate(,,,,, void *release_handle_arg)*/
   } loCaller;

typedef struct loTagPair
   {
    loTagId   tpTi;
    loRealTag tpRt;
    void     *tpAP; /* identifier of AccessPath */
   } loTagPair;

typedef struct loTagState
   {
    FILETIME tsTime;
    HRESULT  tsError;
    int      tsQuality;
   } loTagState;

/* NOTE: if tsTime.dwHighDateTime == 0 then 
         tsTime.dwLowDateTime should contain index in the timestamp array
         (see loCacheTimestamp()). Time from timestamp array will 
         be substituted when actual reading occure. */

typedef struct loTagValue
   {
    VARIANT    tvValue;
    loTagState tvState;
    loTagId    tvTi;
   } loTagValue;


/* loDriver contains all driver-specefic information. All fields
   can be set to 0 */

typedef struct loDriver
   {
    void *ldDriverArg; /* user-defined parameter for passing back using
     loDriverArg() to all loDriver:: functions */
    loMilliSec ldRefreshRate; /* Granularity for client's UpdateRate > 0 */
                              /* 0 mean implementation dependent default */
                              /* It's better to set it explicitly ****** */
    loMilliSec ldRefreshRate_min; /* The shortest possible UpdateRate */
                                  /* 0 mean implementation dependent default */
    unsigned ldQueueMax; /* the limit of queued requests (mostly from Async
                            operations). Value 0 mean reasonable default */
    unsigned ldFlags; /* loDF_XXXX constants */
    char     ldBranchSep; /* single character branch separator for
                             IOPCBrowseAddressSpace. if = 0 then FLAT */

   HRESULT (*ldAskItemID)(const loCaller *,
                          loTagId *ti, void **acpa,  /* return values */
                          const loWchar *itemid, const loWchar *accpath,
                          int vartype, int goal);
                      /* Called when client trying to AddItem(), ValidateItem()
   and so on with an unknown tag. vartype indicates requested datatype,
   usally it is VT_EMPTY. The exact goal of each call is indicated by goal.
   It may be one of loDAIG_XXXX constans.
   Driver may return OPC_E_INVALIDITEMID, OPC_E_UNKNOWNITEMID, OPC_E_UNKNOWNPATH
   or E_FAIL when the tag cannot be created.
   Also driver may find an existing or create new tag and return S_OK.
   In this case returned *ti will help the server to identify requested tag.
   Also driver may return driver-dependent key for specified accpath in *acpa.
   this key will be transferred to driver in ldReadTags()/ldWriteTags() */

    int (*ldWriteTags)(const loCaller *,
                       unsigned count, loTagPair taglist[], VARIANT values[],
                       HRESULT error[], HRESULT *master_err, LCID);
    /* Called for writing tags into controller/driver.
   A driver have to write listed tags into device. Also <error> should be set
   for each handled tag. If a tpTi in taglist is 0 driver should ignore this tag
   (and don't touch the appropriating error[]). In the case of an error driver
   have to set *master_err to S_FALSE (or left it unchanged when all is ok).

   The values[] passed as they are specified by a client. Conversion to canonical
   datatypes may be reqired, also LCID (group-specefic) may be used in such
   conversion. The driver may modify the passed values[] so they can be converted
   "in-place".

   Driver may also change some of taglist[].tpTi to 0.
   If driver return loDW_TOCACHE then lopc will put values with non-zero tpTi
   into cache.
   If the driver return loDW_ALLDONE then none of values will be copied to cache.

   Naturally, driver may update the cache explicitly via loUpdateCache().
    */

   loTrid (*ldReadTags)(const loCaller *,
                        unsigned count, loTagPair taglist[],
                        VARIANT values[], WORD qualities[],
                        FILETIME stamps[], HRESULT errs[],
                        HRESULT *master_err, HRESULT *master_qual,
                        const VARTYPE vtype[], LCID);
   /* Called for reading tags from controller/driver
      to satisfy clients' requests for DEVICE reading.
   Driver may actually update the cache and/or fill the output parameters.
   Possible return values:
   - a value, returned by loCacheUpdate() or loCacheUnlock(), the LightOPC will
     wait until the specified transaction completed ant then return cached values;
   - loDR_CACHED  -- all data is already in cache, no waiting necessary;
   - loDR_STORED  -- driver have stored actual values in values[].

   In the case of a Refresh request the <values> will be 0 as well as
   qualities, stamps and errs thus driver must not fill these output parameters
   and must not return loDR_STORED.

   If the driver returns loDR_STORED the returned values will be transferred to
   client "as is" that ensure athomicity of "device read" operations. Thus driver
   have to convert returned values to vtype[] & LCID requestd by client.
   Also driver have to update the cache because the returned values will not be
   placed in the cache automatically.

   If driver returns other than loDR_STORED the cached values will be posted to
   client and athomicity of this portion of data can not be guaranted.
   The master_err master_qual should be set to S_FALSE if the driver set
   any of errs[] and qualities[] to values other than S_OK and GOOD_XXX
   respectively.

   If a tpTi in taglist is 0 driver have to ignore this tag.

   On another hand, driver may forcibly set a tpTi/tpRt to 0 if it decided to
   return value other than loDR_STORED. The LOPC will get from cache only tags
   with non-zero tpTi. Therefore driver may perform device read only for some
   tags in a request.
   */


   void (*ldConvertTags)(const loCaller *,
                      unsigned count, const loTagPair taglist[],
                      VARIANT values[], WORD qualities[], HRESULT errs[],
                      HRESULT *master_err, HRESULT *master_qual,
                      const VARIANT source[], const VARTYPE vtype[], LCID);
   /* This function is called to convert (localize) those tags that have loTF_CONVERT
      set after they have been read from CACHE.
      For tags read from DEVICE the ldRadTags() should perform such conversion.

      This function have convert source[] to values[] according requested
      vtype[] & LCID. The values[] might be the same as source[].
      It also may modify errs[] and qualities[] when conversion can't be done.
      The master_err & master_qual are also must be set to S_FALSE if any
      errors occured.
      This function have to ignore the tags with taglist[].tpTi is 0.
      If all conversions are completed successfully or no conversion
      performed at all (as in case of empty taglist[]) then
      the master_err & master_qual must left unchanged.

      Unlike other ldXXXX callbacks the ldConvertTags() might be called
      a) very often;
      b) from unclear state of the lightopc library.

      Therefore there are following limitations:
      a) loClientName(), loClientArg(), loDriverArg() can be called freely.
      b) loTridWait(), loSetState() must not be called due to deadlock.
      c) calling of other lightopc functions (referencing to loCervice / loClient)
         may decrease performance.
      d) this function must work fast and must not wait for a event due
         to performance reason.

      See loTF_CONVERT for additional info.

⌨️ 快捷键说明

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