API Manager Classes

WinCC OA provides a class "Manager" that already contains all basic functions required for a manager. For each manager it is necessary to derive another class from this class in which the specific functions of the new manager are implemented. The derived class contains a number of virtual functions that the new manager can and, in some cases, must implement.

Notes

Note: If you are using an API manager or driver that uses DLLs with a new version of WinCC OA, if must be relinked.
Note: When starting such a manager, the DLLs must be located in a directory in the DLL search path.
CAUTION: The length of a manager name is limited to 19 characters in the WinCC OA console.
Note: As of WinCC OA release 3.9 the function dpQueryDisconnect() has only two parameters instead of the usual three. The parameter "del" has been removed. Due to compatibility reasons the third parameter value (e.g. PVSS_FALSE) has to be deleted from the source.

Note on DLL search path

The program looks for DLLs in the following directories in this order:

  • the directory in which the executable is located

  • Windows system directories

  • all directories in the PATH environment variable

For an example see the DemoManager.

Initialization, managerState, dispatch()

When deriving your own manager class, ensure that the constructor initializes the base class properly, otherwise no connection can be made.

The managerState must be observed in all cases: for example, a connection to the Event Manager should only be made when managerState is set to STATE_ADJUST. Further processing can only take place when it is set to STATE_RUNNING. These states are set internally and should always only be read.

Messages are only received and sent when dispatch() is called. (However, messages are always sent when the internal message puffer is full (current size: 4096 bytes)). If dispatch() is not called regularly, the entire communication to the manager is locked and cannot, for example, receive any hotlink messages).

Use of alias names in the API manager

If you want to use alias names of DP elements in an API manager, you can get the DP identifiers or the names of the DP elements for the alias names and vice versa using the following functions:

Alias --> Name:

//gets the DP name with the aid of the DPIdentifier
Manager::getDpIdentificationPtr()->getName(const char *alias, char *&name) 

Alias --> DpIdentifier:

//gets the DPIdentifier, (in this case the alias names have to begin with "@")
Manager::getId(const char *alias, DpIdentifier &dpId) 

Name --> Alias:

//gets the alias name with the aid of the DP identifier
Manager::getDpIdentificationPtr()->getDpAlias(const char *dp, CharString &alias) 

DpIdentifier --> Alias:

//gets the alias name with the aid of the DpIdentifier
Manager::getDpIdentificationPtr()->getDpAlias(const DpIdentifier &dp, CharString &alias)  

Error Handling

There is a general error handler class in WinCC OA. This class represents an error handler used by each manager. Depending on the -log flags given on manager startup, the error messages are either written into the PVSS_II.log file and/or to stderr. The errors can also be written into a database. With ExternErrHdl-Plug-in you can implement an extension that writes into a database.

If the ErrHdl finds a shared library/dll with the name "ExternErrHdl" with one of the extensions ".so", ".shlib", ".dll" or "libExternErrHdl" (.dll only on Windows, .so or .shlib only on non-Windows platforms) in the bin directory of the project it will load this on startup, call extern "C" { ExternErrHdl *createExternErrHdl(); } to create an ExternErrHdl subclass instance, and call its handleError(const ErrClass &errorClass) method before it writes to the targets (log file or stderr) specified by the -log option.

If you would like, for example, to write the errors into a database (in addition to the PVSS_II log file) you can use the ExternErrHdl. You have to derive a class from the ExternErrHdl, compile it as shared libb/ and save it in the bin directory as ExternErrHdl shared lib.

The following example shows how to derive a class from the ExternErrHdl.

/* Example of an external Error Handler loaded as shared-lib/dll by the  standard error handler /*
/* On LINUX this class writes the errors to the syslog, on Windows it prints the errors to stderr/*
#ifdef OS_LINUX
#include <syslog.h>
#endif
#include <ExternErrHdl.hxx>
#include <Resources.hxx>
CharString name"
class MyExternErrHdl : public ExternErrHdl
{
 public:
 MyExternErrHdl()
 {
#ifdef OS_LINUX
 name = Resources::getProgName() + "(" + CharString(Resources::getManNum()) + ")";
 openlog((const char*)name, 0, LOG_USER);
#else
 cerr << "Construct ExternErrHdl" << endl;
#endif
 }
 virtual ~MyExternErrHdl()
 {
#ifdef OS_LINUX
 closelog();
#else
 cerr << "Destruct ExternErrHdl" << endl;
#endif
 }
 virtual void handleError(const ErrClass &errorClass)
 {
#ifdef OS_LINUX
 int level = 0;
 switch ( errorClass.getPriority() )
 {
 case ErrClass::PRIO_FATAL: level = LOG_CRIT; break;
 case ErrClass::PRIO_SEVERE: level = LOG_ERR; break;
 case ErrClass::PRIO_WARNING: level = LOG_WARNING; break;
 case ErrClass::PRIO_INFO: level = LOG_INFO; break;
 }
 syslog(LOG_USER + level, "%s", (const char*)(errorClass.getErrorText()));
#else
 cerr << "ExternErrHdl: ";
 errorClass.outStream(cerr);
#endif
 }
};
//This function creates the ExternErrHdl object
extern "C"
{
 __declspec(dllexport) ExternErrHdl *createExternErrHdl()
 {
 return new MyExternErrHdl();
 }
}