📄 lightopc.h
字号:
*/
void (*ldSubscribe)(const loCaller *, int count, loTagPair til[]);
/* Called when a client changing activity of some
groups or tags. Listed tags are became active (when count>0) or inactive
(when count < 0). Initially all tags are inactive. Driver may not update
inactive tags except they are listed explicitly in argument of
ldReadTags().
If driver does not update inactive tags there is good idea to set
QUALITY of these tags to LAST_KNOWN or something other than GOOD.
This call is NOT syncronized with ldReadTags()/ldWriteTags().
NOTE: til[]::tpAP is NULL for this call.
* If loDF_SUBSCRIBE_RAW has NOT been specified:
The LightOPC maintains internal counter of activations for each tag.
Therefore in the case of multiple [de]activations of a tag in several
groups by several clients only the First activation and
the Last deactivation will be transferred to *ldSubscribe().
I.e. the *ldSubscribe() shows an absolute active state for a tag.
Driver may not count usage of every tag. In may count only total number
of active tag (using count argument) and stop updates when this total is 0.
NOTE: loCaller::ca_cli* is NULL in this case.
* If loDF_SUBSCRIBE_RAW has been specified:
Each particular [de]activation will be delivered to *ldSubscribe().
Therfore driver should count [de]activations by itself for each tag.
NOTE: loCaller::ca_cli* is provided in this case.
*/
HRESULT (*ldBrowseAccessPath)(const loCaller *,
const loWchar*, LPENUMSTRING *es);
/* IOPCBrowseServerAddressSpace::BrowseAccessPath()
On call *es points to enpty IEnumString that can be filled
by loEnumStrInsert(). The driver may use it or may create
another one and return it vith RefCount set to 1 */
void (*ldCurrentTime)(const loCaller *, FILETIME *);
/* Driver's own time. This time may
*slightly* differs from system time. */
unsigned (*ldGetErrorString)(const loCaller *,
HRESULT ecode, LCID locale,
loWchar *buf, unsigned wcsize);
/* Driver may translate the driver-specific
error-codes to string. The size is in characters not bytes.
In case of buf or wcsize are 0 driver should return calculated size
of the string. Return values: 0 if ecode is unknown;
<number of characters in the translated string>
not counting terminating NUL if Ok. If buffer is too short then driver
should truncate returned string properly, but returned length have to
be not truncated. */
HRESULT (*ldQueryAvailableLocaleIDs)(const loCaller *,
DWORD* pdwCount, LCID** pdwLcid);
/* The direct entry from IOPCCommon::QueryAvailableLocaleIDs().
pdwLcid must be allocated by CoTaskMemAlloc(). */
int (*ldCheckLocale)(const loCaller *, LCID dwLcid);
/* Test does driver accept dwLcid?
Shuld return 0 if accepts; -1 - if not */
/* The handlers for OPCItemProperties::
For a defined tag all [output] parameters will contain
preallocated values. In this case the tag contains
valid tpTi/tpRt; the tpAP is always 0.
The lightopc does support the 6 special properties and
properies defined through loPropXXX().
A driver may change these preallocated data, though it's
possible to not define these hanlers at all.
See also loClientChain(). */
HRESULT (*ldQueryAvailableProperties)(const loCaller *, const loTagPair *tag,
const LPWSTR szItemID, DWORD *pdwCount,
DWORD **ppPropertyIDs, LPWSTR **ppDescriptions, VARTYPE **ppvtDataTypes);
HRESULT (*ldGetItemProperties)(const loCaller *, const loTagPair *tag,
const LPWSTR szItemID, DWORD dwCount, DWORD *pdwPropertyIDs,
VARIANT **ppvData, HRESULT **ppErrors, LCID);
HRESULT (*ldLookupItemIDs)(const loCaller *, const loTagPair *tag,
const LPWSTR szItemID, DWORD dwCount, DWORD *pdwPropertyIDs,
LPWSTR **ppszNewItemIDs, HRESULT **ppErrors);
} loDriver;
/* the flags for loDriver::ldFlags */
#define loDF_IGNCASE (0x80) /* ignore case for ItemId comparision */
#define loDF_IGNACCPATH (0x40) /* ignore access path in ItemMgmt::AddItem() */
/* If this flag is not set the ldAskItemID() will be called
if either an unknown itemID passed or non-empty access_path specified.
If this flag is set then access_path is ignored and the ldAskItemID()
will be called for an unknown itemIDs only */
#define loDF_NOCONV (0x100)
/* Do not allow conversion from Canonical to Requested type */
#define loDF_NOCOMP (0x200)
/* Do not perform actual comparision of current and "lastsent" values of tags
instead timestamps will be compared. See also loTF_NOCOMP */
#define loDF_CHECKITEM (0x1000) /* cause ldAskItemID() to be called */
/* whether the ItemID is known or not */
#define loDF_CANONAME (0x2000)
/* Example: The ldAskItemId("level.one") returns tag named "level:1".
If the loDF_CANONAME is specified the name of "level:1" will be
assigned to just created OPC Item. It save some memory.
For unnamed tags this flag ignored.
*/
#define loDF_SUBSCRIBE_RAW (0x80000)
/* Affects the loDriver::ldSubscribe().
If specified then each change in activity of a tag in
different groups and by different clients will cause ldSubscribe().
Otherwise, only global changes in activity will be monitored:
"at least one activation" vs. "no activations".
*/
/* 2 following flags changes the empty enumerators returned */
#define loDf_EE_SOK (1) /* return S_OK and empty enumerator */
#define loDf_EE_NULL (2) /* return S_FALSE and NULL enumerator */
#define loDf_EE_SFALSE (3) /* return S_FALSE and empty enumerator (default) */
#define loDf_DWG (0x04) /* Destroy server with all unreleased groups */
#define loDf_NOFORCE (0x08) /* ignore FORCE flag in RemoveGroup() */
/* These 3 flags are specefic for in-proc servers only. They may
improve the performance in case of mixed thread models or decrease in
case of MTA clients */
#define loDf_FREEMARSH (0x10000)
/* Provide CoCreateFreeThreadedMarshaler() for server/group objects */
#define loDf_BOTHMODEL (0x20000)
/* Do CoMarshalInterThreadInterfaceInStream() /
CoGetInterfaceAndReleaseStream() for callback interfaces */
#define loDf_FREEMODEL (0x40000) /* ignored / default */
/* The special return values for ldReadTags() */
#define loDR_CACHED (1)
#define loDR_STORED (2)
/* The special return values for ldWriteTags() */
#define loDW_ALLDONE (0)
#define loDW_TOCACHE (1)
/* Possible goals of a ldAskItemID() call. Additional
constans might be returned in the future. */
#define loDAIG_MASK (0x00f0) /* mask of a main goal code */
/* no subcodes defined yet */
#define loDAIG_LOINT (0x0000) /* LOPC internal needs */
#define loDAIG_ADDITEM (0x0010) /* OPCItemMgt::AddItems() */
#define loDAIG_VALIDATE (0x0020) /* OPCItemMgt::ValidateItem() */
#define loDAIG_BROWSE (0x0030) /* A method of OPCBrowseAddressSpace:: */
#define loDAIG_IPROPERTY (0x0040) /* A method of OPCItemProperties:: */
#define loDAIG_IPROPQUERY (0x0041) /* OPCItemProperties::QueryAvailableProperties() */
#define loDAIG_IPROPGET (0x0042) /* OPCItemProperties::GetItemProperties() */
#define loDAIG_IPROPLOOKUP (0x0043) /* OPCItemProperties::LookupItemID() */
#define loDAIG_IPROPRQUERY (0x0045) /* Query VarType of a tag referenced as property */
#define loDAIG_IPROPRGET (0x0046) /* Readig value of a tag referenced as property */
typedef struct loVendorInfo
{
WORD lviMajor, lviMinor, lviBuild, lviReserv;
char *lviInfo;
} loVendorInfo;
/* In most functions returned int is 0 if OK or an errno const on error
or -1 if no appropriate errno const match */
LO_PUBLIC
int loServiceCreate(loService **result, const loDriver *, unsigned tagcount);
/* The First initialization step (after initing a logging facility :-)
tagcount - is upper limit of nubmer of allocatable tags.
The tagcount is limited only by amount of available memory.
Each tag consumes from (about) 150 (loAddRealTag_b*())
to 250 (other loAddRealTag*()) bytes */
LO_PUBLIC
int loServiceDestroy(loService *se); /* service actually will not be destroyed
upon all connected client releases it. This call is NOT thread safe - no
other calls to se should be issued simultaneously */
LO_PUBLIC
int loClientCreate(loService *se, loClient **cli,
int ldFlags, /* per-client loDf_XXX flags */
const loVendorInfo *vi,
void (*release_handle)(void *, loService *, loClient *),
void *release_handle_arg);
/* create new client connection and attach it to the service. Returned pointer
*cli can be casted to IUnknown* and represents IOPCServer object with all
related interfaces with "ReferenceCount" = 1. Driver have to Release it after
use or passing to a client. vi and other arguments are optional.
release_handle will be called after last Release() */
LO_PUBLIC
int loClientCreate_agg(loService *se, loClient **cli,
IUnknown *outer, IUnknown **inner,
int ldFlags,
const loVendorInfo *vi,
void (*release_handle)(void *, loService *, loClient *),
void *release_handle_arg);
/* create an aggregated server object.
The <outer> should point to containing/outer object (see QI::CreateInstance).
In the *<inner> the created interface pointer will be returned.
NOTE: use *cli to identify the created client, but use
(*inner)->Release() to destroy it, because call (*cli)->Release() will be
delegated to <outer>.
*/
LO_PUBLIC
int loClientChain(loClient *cli,
HRESULT (*qi_chain)(void *rha, loService *, loClient *,
const IID *, LPVOID *),
void (*release_handle)(void *rha, loService *, loClient *),
void *release_handle_arg);
/* Set the qi_chain QueryInterface() wrapper for the server instance cli.
The release handler is changed too. This function is not thread-safe
and may not be used after the interface is passed to client.
A chained object (usally <<rha>>) should delegate AddRef() and Release()
to cli->AddRef/Release.
qi_chain() will be called from inside cli->QueryInterface()
for all server's interfaces before a native interface pointer obtained.
This function is designed for transparent IPersistFile/IOPCSecurity/
IOPCItemProperties implementations.
Returns: 0 / EBADF.
*/
#define loAM_RDWR (1) /* read-write allowed (default) */
#define loAM_RDONLY_OP (2) /* disable write operations */
#define loAM_RDONLY_ADD (4) /* report all tags as read-only for Add/Validate/EnumIetmAttr */
#define loAM_RDONLY_BROWSE (8) /* report all tags as read-only for Browse */
#define loAM_NOREAD_DEV (0x10) /* perform cache read instead of device read */
#define loAM_ERREAD_DEV (0x20) /* error on device read */
LO_PUBLIC
int loClientAccessMode(loService *, loClient *, int accmode);
/* Set the access mode for specified client instance. accmode is loAM_RDWR or
any combination of other loAM_XXXX flags.
*/
LO_PUBLIC
void *loClientArg(loClient *); /* Returns release_handle_arg of the server */
LO_PUBLIC
void *loDriverArg(loService *); /* Returns loDriver::ldDriverArg of the service */
#define loDriverArg(se) (*((void**)se))
LO_PUBLIC
int loAddRealTag(loService *, /* actual service context */
loTagId *ti, /* returned TagId */
loRealTag rt, /* != 0 */
const char *tName,
int tFlag, /* loTF_XXX */
unsigned tRight, /* OPC_READABLE|OPC_WRITEABLE */
VARIANT *tValue, /* Canonical VARTYPE & default valid value */
/*OPCEUTYPE*/int tEUtype,
VARIANT *tEUinfo); /* optional, if tdEUtype is 0*/
/* Create a tag. tdName = 0 is valid but such tag can be accessed only using
loTagId returned by loDriver::ldAskItemID() in loTagId *ti. Thus
that function have to be provided and must to return *ti.
if tdValue = 0 or has VT_EMPTY type the created tag will be visible by client
through IOPCBrowseAddressSpace interface only. This tag must have defined
tdName as "hint string" to describe valid itemIDs. Actual tags have to be
unnamed and will be accessed through GetItemID()/ldAskItemId().
The loRealTag rt will not be used by LightOPC. It rather be passed back to
some driver's callbacks via loTagPair. It's possible to define th loRealTag_
in any manner. */
/* To make tags' creation / searching faster you may do following
(independent) things:
a) use nameless tags and "hint strings";
b) create all named tags first, then unnamed ones;
c) use loDF_CHECKITEM and implement a fast search in ldAskItemID(). */
#define loTF_NOCOMP (loDF_NOCOMP)
/* don't compare item's values on refresh
item is treated as changed if timestamp mismatch */
#define loTF_NOCONV (loDF_NOCONV)
/* disable conversion from Canonical to Requested type */
#define loTF_EMPTY (0x400)
/* make the tag invisible for AddItem()/ValidateItem()
It's the same as empty tdValue except the 6 properties are provided for
tags with non-empty tdValue only */
#define loTF_CONVERT (0x800)
/* force custom conversion for VT_BSTR/VT_DATE/VT_ARRAY|* */
#define loTF_CHECKITEM (loDF_CHECKITEM) /* cause ldAskItemID() to be called */
/* for this tag whether the ItemID is known or not */
#define loTF_CANONAME (loDF_CANONAME)
#define loTF_NOBROWSE (0x4000) /* make the tag invisible for BrowseAddressSpace */
LO_PUBLIC
int loAddRealTag_a(loService *, /* actual service context */
loTagId *ti, /* returned TagId */
loRealTag rt,
const char *tName,
int tFlag, /* loTF_XXX */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -