API Notes

The BIG Don'ts for API Development

Don't pass a pointer to queues or call back methods

Communication of a driver is asynchronous. If you pass a pointer to a callback object, the pointer might not be valid anymore if the callback is executed. The same applies to send/receive queues.

Note: Always pass instantiated objects to callback methods or send/receive queues, or make absolutely sure that the pointer remains valid until the callback appears or the queue object is processed

Don't call WinCC OA methods from another thread

WinCC OA methods are generally not thread safe and not reentrant, therefore they must only be called from the WinCC OA thread.

If a method is called from another thread, e.g. a communication stack, you must implement a queue as an interface to the WinCC OA thread. Writing to and reading from the queue must be properly safeguarded by locking protocols.

You may use the WinCC OA implementation of a mutex (Mutex.hxx, ScopeMutex.hxx).

Don't use blocking code

WinCC OA API components (EWO, CtrlExt, Driver, DrvPlugin, Manager, AccessControlPlugin) are single threaded.

  • Never use any blocking code
  • Never implement a synchronous call

Always consider that a single WinCC OA driver usually services many peripheral devices. If the manager, i.e. the threads waits for a single device to finish with whatever routine, all other devices are also blocked.

Don't use dispatch in any call-back

The Manager::doReceive() function is automatically called by the Manager::dispatch() function for each incoming message. The manager processes incoming messages in the Manager::doReceive() function. Call-back functions are processed by the Manager::dispatch() function.

Call-back functions are e.g.: WaitForAnswer::callBack(), HotLinkWaitForAnswer::hotLinkCallBack(), Manager::doReceive(), CNSObserver::update(), etc.

Don't call the Manager::dispatch() function from any call-back function to avoid recursion and undefined behavior.

Don't call the Manager::dispatch() function in EWO, CtrlExt, Driver, DrvPlugin and AccessControlPlugin, because this is done internally in the framework.

The Manager::dispatch() function should be called only in the Manager::run() function. This is already done and prepared for you in the API Manager example. See: