You are on page 1of 362

$375$™ Advance ADE

Programmer’s Guide

B006-6042-B000
March 2003
The product described in this publication is a licensed product of NCR Corporation.

APTRA is a trademark of NCR Corporation.


Microsoft, Windows, Windows NT, Windows XP, Visual C++, Visual Basic, and ActiveX are registered
trademarks of Microsoft Corporation in the United States and/or other countries.
Adobe, Acrobat and Reader are either registered trademarks or trademarks of Adobe Systems
Incorporated in the United States and/or other countries.
Other brand or product names are trademarks or registered trademarks of their respective companies
or organisations.

This publication supports release 01.04.00 of the NCR APTRA Advance ADE product.

It is the policy of NCR Corporation (NCR) to improve products as new technology, components,
software, and firmware become available. NCR, therefore, reserves the right to change specifications
without prior notice.

All features, functions, and operations described herein may not be marketed by NCR in all parts of
the world. In some instances, photographs are of equipment prototypes. Therefore, before using this
document, consult with your NCR representative or NCR office for information that is applicable and
current.

To maintain the quality of our publications, we need your comments on the accuracy, clarity,
organization, and value of this book.

Address correspondence to:

NCR Financial Solutions Group Ltd.


Information Solutions Feedback
Kingsway West
Dundee
Scotland
DD2 3XX

© 1998 - 2003
By NCR Corporation
Dayton, Ohio U.S.A.
All Rights Reserved.
Federal Communications
Commission (FCC) Radio
Frequency Interference
Statement

Note: This equipment has been tested and found to


comply with the limits for a Class A digital device,
pursuant to Part 15 of the FCC Rules. These limits are
designed to provide reasonable protection against
harmful interference when the equipment is operated
in a commercial environment. This equipment
generates, uses, and can radiate radio frequency energy
and, if not installed and used in accordance with the
instruction manual, may cause harmful interference to
radio communications. Operation of this equipment in
a residential area is likely to cause harmful
interference in which case the user will be required to
correct the interference at his own expense.

This digital apparatus does not exceed the Class A


Canadian Class A limits for radio noise emissions from digital apparatus
Device Declaration set out in the Radio Interference Regulations of the
Canadian Department of Communications.
Le présent appareil numérique n’émet pas de bruits
radioélectriques dépassant les limites applicables aux
appareils numériques de la classe A prescrites dans le
Réglement sur le brouillage radioélectrique édicté par
le ministère des Communications du Canada.

AT&T -- PROPRIETARY
Use pursuant to Company Instructions

APTRA Advance ADE, Programmer’s Guide i


This equipment must be installed and used in strict
Information to User accordance with the manufacturer’s instructions.
However, there is no guarantee that interference to radio
communications will not occur in a particular
commercial installation. If this equipment does cause
interference, which can be determined by turning the
equipment off and on, the user is encouraged to consult
an NCR service representative immediately.

Caution NCR is not responsible for any radio or television


interference caused by unauthorised modifications of
this equipment or the substitution or attachment of
connecting cables and equipment other than those
specified by NCR. Such unauthorized modifications,
substitutions, or attachments may void the user’s
authority to operate the equipment. The correction of
interference caused by such unauthorized modifications,
substitutions, or attachments will be the responsibility of
the user.

AT&T -- PROPRIETARY
Use pursuant to Company Instructions

ii APTRA Advance ADE, Programmer’s Guide


Revision Record

Date Page Description of Change

June 98 All New Publication

Dec. 98 4-11 to Update for software Release 1.03.00.


4-13 New section on UNICODE guidelines.

Mar 00 All Changed SSDS to Advance ADE.


Changed Platform to Advance XFS.

Chap. 4 Visual C++™ references changed to


Release 6.0.
Chap. 5 Code samples for Examples 4 and 5
interchanged.
ByRef added to registration instruction

Chap. 7 Visual C++™ references changed to


Release 6.0.
Chap. 9 .mak file references changed to .dsw/.dsp

Chap. 10 .mak file references changed to .dsw/.dsp


Example 8 clarified.

Front Changed document number.


and Back

App B Text re. Preventing Rebooting deleted.

App E Updated related documentation for this


release of Advance ADE.

Glossary New entry for Advance XFS.

AT&T -- PROPRIETARY
Use pursuant to Company Instructions

APTRA Advance ADE, Programmer’s Guide iii


Date Page Description of Change

Mar. 03 All Updated to support APTRA Advance


ADE release 01.04.00.
Added ‘APTRA Advance ADE’ to footer.
Changed ‘Windows NT’ to ‘Windows NT
or Windows XP’.

xxvi Changed Advance XFS to Self-Service


Support.

1-1, 1-2 Changed Advance XFS to Self-Service


Support.

2-2, 2-3 Changed Advance XFS to Self-Service


Support.

9-13 Changed Advance XFS to Self-Service


Support.

A-3, A-4, Changed Advance XFS to Self-Service


A-5 Support.

Appx. E Updated and added documentation


numbers.

E-4 Removed Database help.

Glossary Changed Advance XFS to Self-Service


Support.

AT&T -- PROPRIETARY
Use pursuant to Company Instructions

iv APTRA Advance ADE, Programmer’s Guide


Table of Contents

Contents

Preface

Preface ................................................................................xxv
About this publication ...............................................xxv
Abbreviations used in this Publication ..................xxvi
Who Should Read This Publication? ......................xxvi
What Is In This Publication? ....................................xxvi
How To Use This Publication ............................... xxviii
Conventions Used .....................................................xxix
Support Information .................................................xxix

Section 1
General

General

Chapter 1
Self-Service Terminal Software

SST System Software .........................................................1-1


Application Layer........................................................1-1
The Self-Service Support Layer .................................1-2
Windows NT or Windows XP Layer........................1-2

APTRA Advance ADE, Programmer’s Guide v


Table of Contents

Chapter 2
PC Development Environment

Overview............................................................................. 2-1
Development Environment.............................................. 2-2
Hardware and Software Requirements ................... 2-2
Development Environment Components ............... 2-2

Chapter 3
Extending Advance ADE Runtime Functionality

Overview............................................................................. 3-1
Why Extend? ...................................................................... 3-2
When to Extend.................................................................. 3-3
How to Extend ................................................................... 3-4
Types of Extension ...................................................... 3-4
BASIC Expressions...................................................... 3-5
External C Functions................................................... 3-6
Worker Classes ............................................................ 3-7

Section 2
External C Functions

External C Functions

External C Functions

Introduction.....................................External C Functions-v

vi APTRA Advance ADE, Programmer’s Guide


Table of Contents

Chapter 4
Developing External C Functions

Overview.............................................................................4-1
Introduction ........................................................................4-2
Description ...................................................................4-2
Development Process..................................................4-2
Designing a Function.........................................................4-3
Naming Conventions..................................................4-3
Data Types....................................................................4-7
External Data Types ....................................................4-9
UNICODE and Advance ADE ................................4-12
File Locations ....................................................................4-15
User-created Function Directories ..........................4-16
Implementing a Function................................................4-17
General ........................................................................4-17
Exporting a Function from a DLL ...........................4-17
Guidelines for Using a Character Array ................4-18
Memory Management ..............................................4-18
Building a DLL .................................................................4-20
Project Settings...........................................................4-20
Creating a Make File .................................................4-20
Build Process ..............................................................4-21
Output File Locations ...............................................4-21
Using the Advance ADE Class mString.................4-22
Registering a Function.....................................................4-23
Registration Entry Data Types ................................4-25
Registering External Data Types.............................4-28
DLL Transfer Locations ..................................................4-29
Single Application Functions...................................4-30

APTRA Advance ADE, Programmer’s Guide vii


Table of Contents

Global Functions ....................................................... 4-30


Testing a Function ........................................................... 4-31
Test Harness............................................................... 4-31
Test Application ........................................................ 4-31
Debugging a Function..................................................... 4-34
Troubleshooting............................................................... 4-35
Problems When Running the Test Application .... 4-35

Chapter 5
External C Function Examples

Overview............................................................................. 5-1
Introduction........................................................................ 5-2
File Names.................................................................... 5-2
File Locations ............................................................... 5-3
Example 1: A Calculation Using a Computer
Worker .............................................................................. 5-4
The Requirement ......................................................... 5-4
Designing the Function .............................................. 5-5
Implementing the Function ....................................... 5-6
Building the DLL......................................................... 5-7
Registering the Function ............................................ 5-7
Testing the Function ................................................... 5-7
Example 2: Data Testing Using a Tester Worker .......... 5-8
The Requirement ......................................................... 5-8
Designing the Function .............................................. 5-9
Implementing the Function ..................................... 5-10
Building the DLL....................................................... 5-10
Registering the Function .......................................... 5-11
Testing the Function ................................................. 5-11
Example 3: Signal Generation Using a Selector
Worker ............................................................................ 5-12

viii APTRA Advance ADE, Programmer’s Guide


Table of Contents

The Requirement .......................................................5-12


Designing the Function ............................................5-13
Implementing the Function .....................................5-13
Building the DLL .......................................................5-14
Registering the Function ..........................................5-15
Testing the Function..................................................5-15
Example 4: Parsing Data Using an Assigner
Worker.............................................................................5-16
The Requirement .......................................................5-16
Designing the Function ............................................5-16
Implementing the Function .....................................5-18
Building the DLL .......................................................5-23
Registering the Function ..........................................5-23
Testing the Function..................................................5-23
Example 5: Using External Data ....................................5-24
The Requirement .......................................................5-24
Designing the Functions...........................................5-25
Implementing the Functions....................................5-26
Building the DLL .......................................................5-31
Registering the Functions.........................................5-31
Testing the Functions................................................5-31

Section 3
Advance ADE Worker
Classes

Advance ADE Worker Classes

Introduction ....................Advance ADE Worker Classes-v


Worker Class Development
Process ................Advance ADE Worker Classes-v

APTRA Advance ADE, Programmer’s Guide ix


Table of Contents

Overview of Development
Stages.................Advance ADE Worker Classes-vi

Chapter 6
Advance ADE Application Overview

Overview............................................................................. 6-1
Advance ADE Application Basics ................................... 6-2
Flow of Control............................................................ 6-2
Control Messages ........................................................ 6-3
Advance ADE Worker Class Names........................ 6-5
Data Messages ............................................................. 6-5

Chapter 7
Design and Implementation Guidelines

Overview............................................................................. 7-1
Designing a Worker Class ................................................ 7-2
Worker Class Concurrency........................................ 7-3
Advance ADE Metaclasses ........................................ 7-3
Worker Class Design Process .................................... 7-5
Defining Literal Types.............................................. 7-19
Implementing a Worker Class ....................................... 7-23
Implementation Guidelines ..................................... 7-23
Implementing Attributes ................................................ 7-25
Example of Attribute Implementation ................... 7-27

x APTRA Advance ADE, Programmer’s Guide


Table of Contents

Chapter 8
Implementation of Worker Classes

Overview.............................................................................8-1
Implementing an Abstract Worker Class .......................8-2
Implementing a Doer Loner .............................................8-3
Doer Worker Types .....................................................8-4
Doer Worker Methods ................................................8-6
Activation .....................................................................8-8
Event Processing........................................................8-13
Deactivation ...............................................................8-16
Implementing a Second Thread ..............................8-21
Implementing a Getter Loner.........................................8-26
mStringGetter.............................................................8-28
mRealGetter................................................................8-28
mIntegerGetter...........................................................8-29
mHandleGetter ..........................................................8-29
Implementing a Putter Loner.........................................8-32
mStringPutter.............................................................8-34
mRealPutter................................................................8-34
mIntegerPutter...........................................................8-35
mHandlePutter ..........................................................8-35
Implementing a Doer Coordinator................................8-38
Activation ...................................................................8-41
Event Processing........................................................8-42
Deactivation ...............................................................8-44
Implementing a Getter Coordinator .............................8-47
Implementing a Putter Coordinator..............................8-49
Implementing a Work Group.........................................8-51
Creating a Getter or Putter Work Group Type .....8-52

APTRA Advance ADE, Programmer’s Guide xi


Table of Contents

Creating a Doer Work Group Type ........................ 8-54


Declaring the Work Group Type ............................ 8-56
Declaring the Work Group Interface...................... 8-58
Single Work Group Interface................................... 8-59
Multiple Work Group Interface .............................. 8-61

Chapter 9
Building and Testing Guidelines

Overview............................................................................. 9-1
Directory Structure ............................................................ 9-2
Building a Worker Class ................................................... 9-3
Automating the Build Process................................... 9-3
Building a Subclass of a Worker Class..................... 9-4
Adding a Worker Class to the Advance ADE
Runtime............................................................................. 9-5
Removing a Worker Class ......................................... 9-8
Testing a Worker Class ..................................................... 9-9
Debugging a Worker Class ............................................ 9-12
Troubleshooting............................................................... 9-13
Problems When Running the Test Application .... 9-13
Possible Problem Sources ........................................ 9-13

xii APTRA Advance ADE, Programmer’s Guide


Table of Contents

Chapter 10
Advance ADE Worker Class Examples

Overview...........................................................................10-1
Introduction ......................................................................10-2
File Names ..................................................................10-2
File Locations .............................................................10-2
Adding Examples to the Advance ADE
Runtime ................................................................10-3
Example Classes ...............................................................10-4
Example 1: Trace........................................................10-4
Example 2: System Time ..........................................10-4
Example 7: Simple Signaller ....................................10-4
Example 3: Date Setter ..............................................10-4
Example 9: Get Date..................................................10-4
Example 4: Switcher..................................................10-5
Example 5: String Searcher ......................................10-5
Example 6: Eject Card ...............................................10-5
Example 8: Convert Handle TM..............................10-6
Example 10: Base String............................................10-6
Example 11: Convert To Upper ...............................10-6

Appendix A
Appendices ADI-2 Interfacing

Overview............................................................................A-1
Introduction .......................................................................A-2
ADI-2 Interfacing Guidelines ..........................................A-3
ADI-2 Interfacing Example..............................................A-5

APTRA Advance ADE, Programmer’s Guide xiii


Table of Contents

Appendix B
Debugging Your Advance ADE Application with
Visual C++™

Overview.............................................................................B-1
Introduction........................................................................B-2
Debugging on the Development PC ...............................B-3
Build Final User Application.....................................B-4
Project Settings ............................................................B-4
Test & Debug Application .........................................B-4
Debugging on an SST........................................................B-6
Debugging on a Remote PC or SST.................................B-7
Locating Errors Using MAP files...................................B-10

Appendix C
Build Errors

Overview............................................................................ C-1
What Happens When a Build Error Occurs? ......... C-1
Types of Errors ........................................................... C-1
Error Entries................................................................ C-2
What To Do When You Get a Build Error .............. C-4
Common Build Errors ...................................................... C-5
Final Build Errors.............................................................. C-7
Worker Factory Build Errors........................................... C-8

Appendix D
Modifying Advance ADE Runtime

Overview............................................................................ D-1

xiv APTRA Advance ADE, Programmer’s Guide


Table of Contents

ASCII/EBCDIC Conversion Functions .........................D-2

Appendix E
Related Documentation

Overview............................................................................ E-1
Advance ADE Documentation ....................................... E-2
Other NCR Documentation............................................. E-5

Glossary
Glossary Glossary ................................................................ Glossary-1

Index
Index Index ............................................................................Index-1

User Feedback Form

APTRA Advance ADE, Programmer’s Guide xv


Table of Contents

xvi APTRA Advance ADE, Programmer’s Guide


List of Figures

List of Figures

Chapter 1
Self-Service Terminal Software

Figure 1-1 SST System Software..................................1-1

Chapter 2
PC Development Environment

Chapter 3
Extending Advance ADE Runtime Functionality

Figure 3-1 Complexity of Extensions..........................3-4

Chapter 4
Developing External C Functions

Figure 4-1 Directory Structure and Registry File


Location......................................................4-15
Figure 4-2 DLL Transfer Locations ...........................4-29

APTRA Advance ADE, Programmer’s Guide xvii


List of Figures

Chapter 5
External C Function Examples

Figure 5-1 Location of External C Function Example


Files............................................................... 5-3

Chapter 6
Advance ADE Application Overview

Figure 6-1 Advance ADE Control Messages and


Signals .......................................................... 6-3
Figure 6-2 Advance ADE Get Data Message ............ 6-6
Figure 6-3 Advance ADE Put Data Message............. 6-6

Chapter 7
Design and Implementation Guidelines

Figure 7-1 Worker Class Definition Window............ 7-5

Chapter 8
Implementation of Worker Classes

Figure 8-1 Getter Class Hierarchy ............................ 8-27


Figure 8-2 Putter Class Hierarchy............................. 8-33

xviii APTRA Advance ADE, Programmer’s Guide


List of Figures

Chapter 9
Building and Testing Guidelines

Figure 9-1 Worker Class Directory Structure ............9-2


Figure 9-2 Worker Class Runtime File
Locations ......................................................9-6

Chapter 10
Advance ADE Worker Class Examples

Figure 10-1 Worker class Runtime File


Locations ....................................................10-3

Appendix A
ADI-2 Interfacing

Appendix B
Debugging Your Advance ADE Application with
Visual C++™

Figure B-1 Local debugging — Project Settings ....... B-5


Figure B-2 Local debugging — Additional DLLs .... B-5
Figure B-3 Remote debugging — Project Settings ... B-9
Figure B-4 Remote debugging — Additional DLLs B-9

APTRA Advance ADE, Programmer’s Guide xix


List of Figures

Appendix C
Build Errors

Appendix D
Modifying Advance ADE Runtime

Appendix E
Related Documentation

xx APTRA Advance ADE, Programmer’s Guide


List of Tables

List of Tables

Chapter 1
Self-Service Terminal Software

Chapter 2
PC Development Environment

Chapter 3
Extending Advance ADE Runtime Functionality

Chapter 4
Developing External C Functions

Table 4-1 Advance ADE Data Types and their


equivalent C/C++ Data Types .................4-7
Table 4-2 Registration Keywords and equivalent
C/C++ Types ............................................4-26
Table 4-3 Registration Keywords ByRef and
equivalent C/C++ Types.........................4-27

APTRA Advance ADE, Programmer’s Guide xxi


List of Tables

Chapter 5
External C Function Examples

Table 5-1 Example File Types .................................... 5-2

Chapter 6
Advance ADE Application Overview

Chapter 7
Design and Implementation Guidelines

Table 7-1 Attribute Literal Types .............................. 7-9


Table 7-2 Message Types .......................................... 7-12
Table 7-3 Enumerated Literal Type Definition
Information................................................ 7-19
Table 7-4 File Reference Literal Type Definition
Information................................................ 7-20
Table 7-5 Float Literal Type Definition
Information................................................ 7-20
Table 7-6 Integer Literal Type Definition
Information................................................ 7-21
Table 7-7 Point Literal Type Definition
Information................................................ 7-21
Table 7-8 String Literal Type Definition
Information................................................ 7-22
Table 7-9 Literal Types and C++ Equivalents ....... 7-26

xxii APTRA Advance ADE, Programmer’s Guide


List of Tables

Chapter 8
Implementation of Worker Classes

Chapter 9
Building and Testing Guidelines

Chapter 10
Advance ADE Worker Class Examples

Table 10-1 Example File Types ..................................10-2

Appendix A
ADI-2 Interfacing

Appendix B
Debugging Your Advance ADE Application with
Visual C++™

Appendix C
Build Errors

Table C-1 Build Error Variables ................................C-2

APTRA Advance ADE, Programmer’s Guide xxiii


List of Tables

Appendix D
Modifying Advance ADE Runtime

Appendix E
Related Documentation

xxiv APTRA Advance ADE, Programmer’s Guide


Preface
Preface

Preface

This publication provides information and guidance on


About this publication extending the functionality of the Runtime component of
APTRA Advance ADE.
This will be necessary only if the extensive range of
resources supplied with the Advance ADE Runtime
cannot fulfil the requirements of the user’s application.
Advance ADE Runtime functionality can be extended in
the following ways:
● By creating BASIC Expressions which extend the
data processing capabilities of the system
● By creating or linking external C functions to extend
the range of functions that can be called from a
BASIC Expression
● By creating Advance ADE C++ Worker classes which
use, or specialise from, the Advance ADE classes
supplied for the purpose.
Development of BASIC Expressions is described in the
APTRA Advance ADE, User’s Guide.
Development and linking of user-created and third party
external C functions, and development of user-created
C++ Worker classes are described in this publication.
To function correctly within the Advance ADE Runtime
environment user-created Worker classes must follow
the design, development and implementation guidelines
contained in this publication.
When developing user-created classes this publication
should be used in conjunction with the APTRA Advance
ADE, C++ Class Reference.

APTRA Advance ADE, Programmer’s Guide xxv


Preface
Preface

References to APTRA Advance ADE are abbreviated to


Abbreviations used in Advance ADE.
this Publication
References to APTRA Self-Service Support are
abbreviated to Self-Service Support.
References to SHUVRQD6 667 'HYLFH 6LPXODWRU )RU :LQGRZV 17Œ
are abbreviated to SST Device Simulator.

This publication is intended for C and C++ programmers


Who Should Read This who are considering extending the functionality of the
Publication? Advance ADE Runtime system.

This publication contains the following information:-


What Is In This
Publication? The General section, comprising:
Chapter 1, “Self Service Terminal Software”, which
describes the components of the Self Service Terminal
Software.
Chapter 2, “PC Development Environment”, which
describes the PC based environment for the
development of C++ classes and C functions.
Chapter 3, “Extending Advance ADE Runtime
Functionality”, which provides an overview of what can
be achieved by extending Advance ADE functionality
and how to decide what method to use.
The External C Functions section, comprising:
Chapter 4, “Developing External C Functions”, which
provides a description of how to develop C data
manipulation functions and how to interface between
Advance ADE Runtime and third party Dynamic Link
Libraries.

xxvi APTRA Advance ADE, Programmer’s Guide


Preface
Preface

Chapter 5, “External C Function Examples”, which


contains examples illustrating the processes described in
Chapter 4.
The Advance ADE Worker Classes section, comprising:
Chapter 6, “Advance ADE Application Overview”,
which describes the structure of an Advance ADE
application and how it works.
Chapter 7, “Design and Implementation Guidelines”,
which describes how to design and develop user-created
Advance ADE Worker Classes.
Chapter 8, “Implementation of Worker Classes”, which
describes how to implement user-created Advance ADE
Worker Classes in C++.
Chapter 9, “Building and Testing Guidelines”, which
contains building and testing information for
user-created Advance ADE Worker Classes.
Chapter 10, “Advance ADE Worker Class Examples”,
which contains the Worker Class examples which are
supplied with Advance ADE.
The Appendices section, comprising:
Appendix A, “ADI-2 Interfacing”, which provides
detailed information and examples on interfacing
between Advance ADE Worker Classes and ADI-2.
Appendix B, “Debugging Your Advance ADE
Application with Visual C++™”, which provides
information on how to debug your own Advance ADE
application code. This chapter is applicable to both
external C functions and user-created C++ Worker
Classes.

APTRA Advance ADE, Programmer’s Guide xxvii


Preface
Preface

Appendix C, “Build Errors”, which provides a list of the


errors that can occur when an Application is built. The
list includes possible causes of the errors and remedies.
Appendix B, “Debugging Your Advance ADE
Application with Visual C++™”, which describes
modifications that you can make to Advance ADE
Runtime.
Appendix E, “Related Documentation”, which
identifies other publications relevant to development of
Advance ADE Applications.
The Glossary, which lists and explains terms used in this
publication in alphabetical order.
The Index, which provides a classified list of topics and
items of information in this publication, with page
references.

The General section and Appendix B, “Debugging Your


How To Use This Advance ADE Application with Visual C++™” are
Publication essential reading for all developers.
Developers who wish to add new C functionality or use
third party DLLs should read the External C Functions
section.
Those who wish to create new Worker Classes should
read the Advance ADE Worker Classes section.

xxviii APTRA Advance ADE, Programmer’s Guide


Preface
Preface

The term <GLOBAL> refers to your global directory; see


Conventions Used the APTRA Advance ADE, User’s Guide.
The term ASCIIZ is used in this publication to mean a
null terminated character array.

If you have a problem using the Advance ADE software,


Support Information carry out the following steps until the problem is
resolved:
1 Refer to the relevant “Troubleshooting” section to
see if you can resolve the problem yourself

2 Contact your internal support personnel for help

3 Contact your local NCR representative.


NCR provides a wide range of support programmes. For
more information, contact your local Account Team.
Should you have any problems using this guide, please
refer to the User Feedback Form at the back of this guide,
where you will find our e-mail address. Please take the
time to reply; your comments are valued.

APTRA Advance ADE, Programmer’s Guide xxix


Preface
Preface

xxx APTRA Advance ADE, Programmer’s Guide


Section 1
General

Chapter 1 Self-Service Terminal Software

Chapter 2 PC Development Environment

Chapter 3 Extending Advance ADE Runtime Functionality

APTRA Advance ADE, Programmer’s Guide


APTRA Advance ADE, Programmer’s Guide
General
Overview

Overview

This section discusses the software components required


for the development of extensions to Advance ADE
Runtime functionality.

APTRA Advance ADE, Programmer’s Guide Section 1-iii


Section 1
Overview

Section 1-iv APTRA Advance ADE, Programmer’s Guide


Table of Contents
Self-Service Terminal Software

Chapter 1
Self-Service Terminal Software

SST System Software 1-1


Application Layer 1-1
The Self-Service Support Layer 1-2
Windows NT or Windows XP Layer 1-2

APTRA Advance ADE, Programmer’s Guide


Table of Contents
Self-Service Terminal Software

APTRA Advance ADE, Programmer’s Guide


Self-Service Terminal Software
1

SST System Software

SST System Software 1

The system software for the 56XX and Personas SST


consists of an Application, Self-Service Support and the
Windows NT or Windows XP operating system.
The illustration below is used to show the interaction
between the different parts of the SST system software
with the Application communicating with Self-Service
Support and Windows NT/Windows XP.

Figure 1-1
SST System Software
1

Application

Self-Service
Support

Windows NT or
Windows XP

The software components are described below.

This layer consists of one or more Advance ADE


Application Layer 1

Applications, which are object oriented, event driven,


multi-tasking applications, built using the APTRA
Author.
The application communicates with Self-Service Support
using the ADI-2 Interface.

APTRA Advance ADE, Programmer’s Guide 1 -1


Self-Service Terminal Software
SST System Software

The Application can also communicate directly with


Windows NT or Windows XP to use its facilities; for
example, semaphores and multi-tasking.

This layer provides an operating system-independent


The Self-Service interface which allows the Application to access all the
Support Layer 1
SST capabilities.
The main features of Self-Service Support are:
● Task initialisation and control.
● System utilities.
● Access to terminal devices.
● Status monitoring.
● Configuration and Diagnostics.
The Applications interface with Self-Service Support is
called the Application / Device Interface version 2
(ADI-2).
ADI-2 provides the following main features:
● Application to Device Interface.
● File management .
● Inter-task communications.
● Non-volatile RAM (NVRAM) interface.
More detailed information concerning the Self-Service
Support software can be found in the APTRA Self-Service
Support, Programmer’s Reference.

The Windows NT or Windows XP operating system is


Windows NT or the base of the SST system software. It is used to provide
Windows XP Layer 1
features such as multi-tasking capabilities, semaphores
and so on.

1-2 APTRA Advance ADE, Programmer’s Guide


Table of Contents
PC Development Environment

Chapter 2
PC Development Environment

Overview 2-1

Development Environment 2-2


Hardware and Software Requirements 2-2
Development Environment Components 2-2

APTRA Advance ADE, Programmer’s Guide


Table of Contents
PC Development Environment

APTRA Advance ADE, Programmer’s Guide


PC Development Environment
2

Overview

Overview 2

This chapter describes the PC environment required for


Advance ADE development.

APTRA Advance ADE, Programmer’s Guide 2 -1


PC Development Environment
Development Environment

Development Environment 2

This chapter describes the PC environment and tools that


are required by a programmer to develop external C
functions and Worker Classes to extend the Advance
ADE Runtime.

The Development Environment is based on a PC


Hardware and running the Microsoft Windows NT or Windows XP
Software operating system, which has at least the minimum
Requirements 2 hardware requirements detailed in the APTRA Advance
ADE, User’s Guide, and the following software:
● Microsoft Windows NT or Windows XP
● NCR Self-Service Support
● Microsoft Visual C++™ Release 6.0 compiler
● Advance ADE
- includes APTRA Author and Advance ADE
Runtime Components
● NCR SST Device Simulator (optional).
For version information, refer to the APTRA Advance
ADE, User’s Guide.

The base development environment consists of the


Development following:
Environment ● Visual C++™ compiler
Components 2

The Visual C++™ compiler is the tool used to


produce the executable code for user-created C++
Worker Classes and external C functions.

2-2 APTRA Advance ADE, Programmer’s Guide


PC Development Environment
Development Environment

● Advance ADE

The APTRA Author, which is included in the


Advance ADE product, is used to create and run
Advance ADE Applications such as those used to test
user-created Worker Classes or external C functions.

● Self-Service Support

Self-Service Support is required to give a full test


environment. This enables the Application to run on
a PC as if it were an SST.

● SST Device Simulator

The SST Device Simulator is used to simulate any


devices that may exist on an SST. This allows testing
of the interaction between user-created Advance
ADE Worker Classes and the devices.

● Advance ADE Runtime Components

The Advance ADE Runtime comprises the Worker


and other classes supplied with Advance ADE which
are required for the execution of an Advance ADE
Application. The Advance ADE Header Files and
Libraries are supplied as part of the Runtime. These
are supplied so that user-created Worker Classes can
subclass from or use the Advance ADE classes.

APTRA Advance ADE, Programmer’s Guide 2-3


PC Development Environment
Development Environment

2-4 APTRA Advance ADE, Programmer’s Guide


Table of Contents
Extending Advance ADE Runtime Functionality

Chapter 3
Extending Advance ADE
Runtime Functionality

Overview 3-1

Why Extend? 3-2

When to Extend 3-3


Uses 3-3

How to Extend 3-4


Types of Extension 3-4
BASIC Expressions 3-5
Uses 3-5
When to use 3-5
Limitations 3-5
Development 3-6
External C Functions 3-6
Uses 3-6
When to use 3-7
Limitations 3-7
Development 3-7
Worker Classes 3-7
Uses 3-8
When to use 3-8
Development 3-8

APTRA Advance ADE, Programmer’s Guide


Table of Contents
Extending Advance ADE Runtime Functionality

APTRA Advance ADE, Programmer’s Guide


Extending Advance ADE Runtime Functionality
3

Overview

Overview 3

This chapter provides an overview of extending


Advance ADE Runtime functionality.
Why Extend? describes why it is useful to extend the
Advance ADE Runtime.
When to Extend contains guidelines for choosing which
type of Advance ADE extension to use for a particular
problem.
How to Extend discusses the three different methods
used for Advance ADE extensions.

APTRA Advance ADE, Programmer’s Guide 3 -1


Extending Advance ADE Runtime Functionality
Why Extend?

Why Extend? 3

Advance ADE supplies a large array of Workers which


handle NCR devices and self-service processing
activities.
The Advance ADE Worker Classes are each designed to
have very specific functionality so that a group of them is
required to perform an entire transaction. This
maximises the flexibility of Advance ADE and gives you
control over the way in which particular tasks are
performed.
It is better that you group the supplied Workers
together, rather than creating a large complex Worker
Class with all the functionality.
However, it would not be possible to supply Advance
ADE Worker Classes for every specific use of a third
party device or every type of data processing and so on.
Therefore Advance ADE has been designed to be user
extensible. This gives you the ability to customise
Advance ADE with your own functionality to cope with
your unique processing needs.

3-2 APTRA Advance ADE, Programmer’s Guide


Extending Advance ADE Runtime Functionality
When to Extend

When to Extend 3

You should look at the supplied classes and functions


before deciding whether a new external C function or
Worker Class is actually required.
To help you decide whether there is an Advance ADE
Worker Class that suits your needs you should look at
the list provided in the APTRA Advance ADE, User’s
Guide.
In addition, you should note that some parts of the
supplied Advance ADE Runtime can be customised to
suit your own needs. For more information see
Appendix B, “Debugging Your Advance ADE
Application with Visual C++™”.

Uses 3

The following is a short list of typical situations where an


Advance ADE Extension would be used:
● You want to use an existing library of functions.
● You want to use a new device (typically supplied by
a third party), that is not supported by the supplied
classes.
● You want to use an arithmetic formula (e.g. a loan
interest calculation) or algorithm (e.g. a different
type of note mix) which is needed within an
application and not supplied in Advance ADE.

APTRA Advance ADE, Programmer’s Guide 3-3


Extending Advance ADE Runtime Functionality
How to Extend

How to Extend 3

There are three types of Advance ADE extension:


Types of Extension 3

● BASIC expressions
● External C functions
● User-created Worker Classes
Figure 3-1 shows the comparative complexity of the
types of extension.

Figure 3-1 Low


Complexity of Extensions
3
BASIC Expressions
COMPLEXITY

External C Functions

Worker Classes
High

3-4 APTRA Advance ADE, Programmer’s Guide


Extending Advance ADE Runtime Functionality
How to Extend

BASIC expressions are the simplest form of Advance


BASIC Expressions 3

ADE Extensions and can be produced by non-C


programmers. They allow you to produce your own
customised data processing.
Since this type of extension is the easiest to do, it should
be the first type that you should consider when deciding
what type is required for your particular processing task.
If BASIC expressions cannot provide the required
functionality then you should next consider external C
functions.

Uses 3

The following is the list of uses for a BASIC expression:


● It can be used for a calculation which needs to be
performed within an application
● It can be used for some form of data manipulation
(for example, string formatting) within an
application.

When to use 3

The following is a list of guidelines for when a BASIC


expression should be used rather than other types of
extension:
● The algorithm to be developed is simple
● The algorithm is to be produced by a programmer
who is unfamiliar with C.

Limitations 3

The following limitations of BASIC expressions should


be considered before deciding on the type of extension
that is required:
● If the algorithm is too complex, a BASIC expression
can become large and difficult to maintain

APTRA Advance ADE, Programmer’s Guide 3-5


Extending Advance ADE Runtime Functionality
How to Extend

● BASIC expressions tend to be slower than the other


extensions when the processing is complicated, so it
is possible that performance could be an issue.

Development 3

Since they are designed to be used by non C


programmers, information on developing BASIC
expressions is included in the APTRA Advance ADE,
User’s Guide.

External C functions as Advance ADE Extensions


External C Functions 3

provide much more flexibility than BASIC expressions,


but they cannot be produced by non-programmers. They
allow you to produce your own customised data
processing and to access external libraries.
Since this type of extension is easier to implement, you
should consider it before creating a new Worker Class. If
external C functions cannot give you the required
flexibility then creating a new Advance ADE Worker
Class is your only other possibility.

Uses 3

External C functions can be used in the following ways:


● For a complex calculation which needs to be
performed within an application
● For data manipulation (e.g. string formatting) within
an application
● To interface to an external library (possibly supplied
by a third party) that supplies an extension to the
Advance ADE functionality (e.g. a graphics library).

3-6 APTRA Advance ADE, Programmer’s Guide


Extending Advance ADE Runtime Functionality
How to Extend

When to use 3

External C functions should be used rather than other


types of extensions in the following circumstances:
● When the particular operation cannot be performed
easily (or at all) using a BASIC Expression
● When an existing library of functions needs to be
used
● When performance is an issue.

Limitations 3

The following limitations of external C functions should


be considered before deciding whether a C function or a
new Worker Class is required for the particular task:
● They are not as closely integrated with the Advance
ADE system as Worker Classes, and so are not as
easy for application authors to understand and use
● They may not be as re-usable as Worker Classes
● They do not have the flexibility of Work Groups and
Attributes that Worker Classes have
● They cannot handle complex tasks as well as Worker
Classes.

Development 3

If you decide that external C functions offer sufficient


functionality to meet your requirements, refer to Section
2, “External C Functions”.

The development of user-created Worker Classes


Worker Classes 3

provides the most flexible approach to expanding the


Advance ADE functionality. However these extensions
can only be produced by C++ programmers.

APTRA Advance ADE, Programmer’s Guide 3-7


Extending Advance ADE Runtime Functionality
How to Extend

Since this type of extension is the most complex to


develop, requiring more knowledge of Advance ADE
and C++ skills, it should be considered only after the
other forms of Advance ADE extensions have been
discarded as possibilities.

Uses 3

The following is a list of uses for user-created Worker


Classes:
● To include existing ADI-2 interface code
● To access a new device (typically third party) from
an Advance ADE Application.

When to use 3

User-created Worker Classes should be used rather than


other types of extensions in the following circumstances:
● When you want to use existing ADI-2 code
● When you require the functionality of an external C
function and the flexibility of Attributes and Work
Groups
● When performance is an issue
● When re-use is an issue.
There are virtually no limitations on what a Worker
Class can be used for or when it should be used, as
demonstrated by the wealth and diversity of the
supplied Advance ADE Worker Classes.

Development 3

If you decide that the functionality offered by Worker


Classes is what you require, refer to Section 3, “Advance
ADE Worker Classes”.

3-8 APTRA Advance ADE, Programmer’s Guide


Section 2
External C Functions

Introduction External C Functions-v

Chapter 4 Developing External C Functions

Chapter 5 External C Function Examples

APTRA Advance ADE, Programmer’s Guide


APTRA Advance ADE, Programmer’s Guide
External C Functions
Overview

Overview

This section provides a description of how to develop C


functions, and how to interface to third-party DLLs.
Chapter 4, “Developing External C Functions” describes
the general use of external C functions in an Advance
ADE Application and the development of your own
external C functions. Chapter 4, “Developing External C
Functions” contains examples of the use of external C
functions.

Customisation of Supplied Functions 0

Some of the external functions supplied with the


Advance ADE Runtime can be customised to suit your
own needs. For more information see Appendix D,
“Modifying Advance ADE Runtime”.

APTRA Advance ADE, Programmer’s Guide Section 2-iii


Section 2
Overview

Section 2-iv APTRA Advance ADE, Programmer’s Guide


External C Functions
Introduction

Introduction

External C functions can be user-created or supplied in


third-party libraries. In either case they are accessed by
Advance ADE as external Dynamic Link Libraries
(DLLs).
An external C function is used in exactly the same way
as the supplied BASIC Expressions. These expressions
are used as attributes by the Tester, Assigner or any of
the Computer Workers. External C functions can be used
for data manipulation or to allow access to a third-party
library (for example, a graphics library).
Before deciding whether a new external C function has
to be coded, you should check the On-line Help for
information about the capabilities of the supplied BASIC
Expressions.

APTRA Advance ADE, Programmer’s Guide Section 2-v


Section 2
Introduction

Section 2-vi APTRA Advance ADE, Programmer’s Guide


Table of Contents
Developing External C Functions

Chapter 4
Developing External C
Functions

Overview 4-1

Introduction 4-2
Description 4-2
Development Process 4-2

Designing a Function 4-3


Naming Conventions 4-3
Data Types 4-7
External Data Types 4-9
UNICODE and Advance ADE 4-12

File Locations 4-15


User-created Function Directories 4-16

Implementing a Function 4-17


General 4-17
Exporting a Function from a DLL 4-17
Guidelines for Using a Character Array 4-18
Memory Management 4-18

APTRA Advance ADE, Programmer’s Guide


Table of Contents
Developing External C Functions

Building a DLL 4-20


Project Settings 4-20
Creating a Make File 4-20
Build Process 4-21
Output File Locations 4-21
Using the Advance ADE Class mString 4-22

Registering a Function 4-23


Registration Entry Data Types 4-25
Registering External Data Types 4-28

DLL Transfer Locations 4-29


Single Application Functions 4-30
Global Functions 4-30

Testing a Function 4-31


Test Harness 4-31
Test Application 4-31

Debugging a Function 4-34

Troubleshooting 4-35
Problems When Running the Test Application 4-35

APTRA Advance ADE, Programmer’s Guide


Developing External C Functions
4

Overview

Overview 4

This chapter provides a description of how to develop


external C functions.
The Introduction describes what external C functions
are, and the procedure for developing an external C
function.
The stages in the development of an external C function
are described as follows:
● “Designing a Function” on page 4-3
● “Implementing a Function” on page 4-17
● “Building a DLL” on page 4-20
● “Registering a Function” on page 4-23
● “Testing a Function” on page 4-31.

APTRA Advance ADE, Programmer’s Guide 4 -1


Developing External C Functions
Introduction

Introduction 4

An external C function is a C function which is contained


Description 4

in a DLL (the type of DLL required is defined in


“Building a DLL” on page 4-20).
External C functions are used in exactly the same way as
the supplied BASIC Expressions. These expressions are
used as attributes by the Tester, Assigner or any of the
Computer Workers. External C functions can be used for
data manipulation or to allow access to a third-party
library (for example, a graphics library).
External C functions can be user-created or supplied in
third-party libraries. In either case they are accessed by
Advance ADE as external Dynamic Link Libraries
(DLLs).
Before deciding whether a new external C function is
required, refer to the On-line Help for information about
the capabilities of the supplied BASIC Expressions.

The external C function is developed and stored in a


Development Process 4

DLL.
The properties of the function are registered with
Advance ADE so that the function can be used as if it
was a BASIC Expression.
The expression is then set up in an instance of one of the
Worker Class types mentioned above and the function is
executed.

4-2 APTRA Advance ADE, Programmer’s Guide


Developing External C Functions
Designing a Function

Designing a Function 4

This section describes the process of designing an


external C function.

An external C function must follow certain Advance


Naming Conventions 4

ADE conventions regarding the naming of the function


and its parameters.
These conventions are designed to allow the function to
be called in the same way as an intrinsic function.
In a BASIC Expression external functions have the same
syntax as intrinsic functions, as follows:

FunctionName( ParameterList )

where ParameterList is a list of comma separated


parameters, which can be a null list. The number of
parameters is determined by the design of the function.
Examples of this syntax would be:

Interest(Amount, Time%, InitialAmount )

DayOfWeek%()

It is recommended for maintainability that the function


names and parameters follow the rules for Advance
ADE Data Types; see “Data Types” on page 4-7.

External Function Names 4

The rules governing the naming of a function are as


follows:
● The name should be meaningful; that is, it should
indicate the purpose of the function

APTRA Advance ADE, Programmer’s Guide 4-3


Developing External C Functions
Designing a Function

● The name has to comply with the constraints that the


compiler puts on the length and on the types of
characters that can be used
● The name must be unique; this includes being
different from the intrinsic functions supplied with
Advance ADE and other external functions. If it is
not an Invalid Name error will occur. All the
function names already in use can be found in the
registry.scr and userfuns.scr files, containing supplied
Advance ADE function names and user-created
function names respectively. One way of avoiding
this problem is to use an alias; see the following
section “External Function Aliases”.
● The name is case sensitive
● The actual function name must be identical to the
name used in the BASIC Expression, unless an alias
is being used; see the following section “External
Function Aliases”.
The C/C++ data type returned by the function will be
converted to one of the Advance ADE Data Types, as
defined in the On-line Help, unless an external data type,
mHandle is being used; see “External Data Types” on
page 4-9.

External Function Aliases 4

A function is given an alias for one of two reasons: the


function name is already in use, or a more meaningful
name is required. For example, the alias can include a
type-declaration suffix.

4-4 APTRA Advance ADE, Programmer’s Guide


Developing External C Functions
Designing a Function

The following are the rules governing the alias:


● It must begin with a letter.
● It must be unique; this includes being different from
the intrinsic functions supplied with Advance ADE
and other external functions. If it is not different an
Invalid Name error will occur.
● It is case sensitive.
● It can be up to 254 characters in length.
● It can be used to provide the function name with a
type-declaration suffix. This is done to make
functions easier to use since the function’s return
type can be found simply by examining its name.
This type-declaration suffix is used in BASIC
variables to define type and is used in functions to
define return type; see section “Data Types” on page
4-7.
● It must be used instead of the original function name

Parameters 4

The rules governing the naming of an external function


parameter are as follows:
● The name must be unique, and this includes being
different from the intrinsic functions supplied with
Advance ADE.
● The name is case sensitive.
● The name used in the BASIC Expression can be
completely different from the actual parameter
name.
● The name has a type-declaration suffix which is used
in BASIC variables to define type and is used here to
define the parameter data type; see section “Data
Types” on page 4-7.

APTRA Advance ADE, Programmer’s Guide 4-5


Developing External C Functions
Designing a Function

The Advance ADE Data Type parameters in the BASIC


Expression will be converted to the C/C++ data type of
the actual parameter unless an external data type,
mHandle is being used; see “External Data Types” on
page 4-9.

4-6 APTRA Advance ADE, Programmer’s Guide


Developing External C Functions
Designing a Function

An external C function can use any C/C++ language


Data Types 4

data type as a parameter or return type.


Structure data types can be passed only by reference. All
other data types can be passed by value or reference.
For information on how to use structures or other forms
of data unknown to Advance ADE, refer to “External
Data Types” on page 4-9.
The Advance ADE Data Types and their equivalent
C/C++ Data Types are shown in Table 4-1.

Table 4-1 Advance ADE Data


Suffix C/C++ Data Types
Advance ADE Data Types and their Type
equivalent C/C++ Data Types
Real none float
float*
double
double*
long double
long double*

Integer % unsigned short


unsigned short*
short
short*
unsigned int
unsigned int*
int
int*
long
long*
unsigned long
unsigned long*

APTRA Advance ADE, Programmer’s Guide 4-7


Developing External C Functions
Designing a Function

Advance ADE Data


Suffix C/C++ Data Types
Type

String $ unsigned char


unsigned char*
char
char * (ASCIIZ)
mString (Advance ADE
Class)
mString*

Handle ? external data type

The table shows all the possible conversions for a


particular Advance ADE Data Type.
For example, if a parameter in a BASIC Expression has
no suffix, it will be treated as Real, and can be used if the
actual function parameter is a float , a double or a long
double, with a conversion being done if necessary.

Similarly, if the function returns a float, a double or


long double, and the function name does not have a
suffix, then the return type will be converted to a Real
Advance ADE Data Type (if a conversion is required).

Note: It makes no difference to the Advance ADE Data


Type whether the parameters or return values are passed
as references. For example, if an integer or an int* is
passed as a parameter of a routine; the Advance ADE
Data Type for the parameter is still an Integer with a ‘%’
suffix.

When a value is being converted from a C/C++ data


type to an Advance ADE Data Type or the other way
round, the values are checked to see if they are within
the valid range. If they are not a Value Out Of Range
error will occur.

4-8 APTRA Advance ADE, Programmer’s Guide


Developing External C Functions
Designing a Function

For example, an error will occur, if a function with a


short parameter has a Advance ADE Integer Type
passed to it whose value is outwith the maximum and
minimum limits of a short data type.

Note: A conversion from an Advance ADE String Type


to an unsigned char or char, has an additional test that
checks whether the String contains only one character
and that it is within the valid range.

The exact meaning of the different Advance ADE Data


Types can be found in the On-Line Help.

Using Character Arrays 4

To use a character array as a parameter, follow the


instructions described in “Guidelines for Using a
Character Array” on page 4-18.

Using the Advance ADE Class mString 4

If an Advance ADE Class mString is used as a parameter,


an external C function must be produced (see the APTRA
Advance ADE, C++ Class Reference, “mString”). For more
information, refer to “Implementing a Function” on page
4-17.
You must #include the Advance ADE file mcore.h in the
source code.

As previously described, Advance ADE does not


External Data Types 4

support data structures. However, there are two ways to


get round this:
● Use a String to hold the structure as an array of
ASCII Characters, which can be manipulated using
BASIC Expressions.

APTRA Advance ADE, Programmer’s Guide 4-9


Developing External C Functions
Designing a Function

● Use an Advance ADE Handle as a pointer to the data


structure.
The following sections describe these different ways.

Using a String for External Data 4

A String can be used to hold a structure. This String can


be passed to and from an external function and can be
manipulated directly by Worker Classes which have
BASIC Expressions, such as Assigner.
To use a Character Array as a parameter, refer to the
instructions described in “Guidelines for Using a
Character Array” on page 4-18.

Using a Handle for External Data 4

An Advance ADE Handle can be used to access external


data allowing the set up of your own data types.
For an example of External Data using a Handle, see
Chapter 5, “External C Function Examples”.
The Handle is only a pointer to the data structure as
Advance ADE has no detailed knowledge of the
structure.
The disadvantages of using a Handle are listed below:
● Handles cannot be converted directly by the
supplied Advance ADE Worker Classes into other
Advance ADE Data Types.
● Handles cannot be manipulated directly by the
supplied Advance ADE Worker Classes. They are
simply passed from one Worker to another.
● New external functions or Worker Classes must be
produced to use Handles.

4-10 APTRA Advance ADE, Programmer’s Guide


Developing External C Functions
Designing a Function

As Advance ADE has no detailed knowledge of the


structure, user data types cannot be passed by value to
or from external functions.
However, a pointer can be passed to the data structure to
and from the external function.
For example, if the function is to update a user structure
and return the modified value, the C function
declaration would take the following form:

UserOutputStruct *
UserFunction( UserInputStruct * )

the BASIC Function call would take the form:

UserFunction( UserStructure? )

In BASIC Expressions parameters and functions


returning external data types have the suffix “?”; see
“Data Types” on page 4-7.
When a function is registered (see “Registering a
Function” on page 4-23), and the return data type is not
recognised, in this case UserOutputStruct, it is
assumed that it is an external data type and a Handle is
created.
For type checking purposes, this Handle uses the type
name converted to a string, the Handle ID, in this
example “UserOutputStruct”. For more information on
use of the Handle ID for type checking in a Worker
Class, see APTRA Advance ADE, C++ Class Reference,
“mString”.
If the parameter types have been setup incorrectly at the
time of registering a function, type checking may not be
performed accurately. This is due to type checking being
done by Advance ADE and not C++. This would result

APTRA Advance ADE, Programmer’s Guide 4-11


Developing External C Functions
Designing a Function

in a Handle with an incorrect ID failing to indicate a


Type Mismatch error.

Note: You are responsible for memory allocation and


deallocation of external data types and this should be
handled by the external functions.

For information on using Worker Classes to process


external data produced by an external function, and to
generate external data that can be passed to an external
function, see Chapter 5, “External C Function
Examples”.

At the heart of all data storage in Advance ADE is the


UNICODE and class “mString”. This stores all data internally as
Advance ADE 4
UNICODE - an internationally recognised standard
character set, which contains all characters commonly
used in information processing. If an mString is created
using a non-UNICODE string, this will be converted to
UNICODE. Similarly, if non-UNICODE raw data is
extracted from an mString, then this will be converted
from UNICODE.
The mString constructors you need to be aware of are:
1 mString(const TCHAR *pChar, const UINT
Offset = 0, const UINT Length = SHRT_MAX);

2 mString(const char *pChar, const UINT


Offset = 0, const UINT Length = SHRT_MAX);

3 mString(const TCHAR Char);

4 mString(const char Char);

5 mString(const BYTE *pByte, const UINT


NumChars, const UINT BytesPerChar);

4-12 APTRA Advance ADE, Programmer’s Guide


Developing External C Functions
Designing a Function

6 mString(const BYTE aByte);

7 mString(const BYTE *pBytes, UINT size);

Constructors 1 and 3 which accept a TCHAR or TCHAR*


expect 16 bit UNICODE characters. No conversion is
performed.
Constructors 2, 4, 5, 6 and 7 which accept a char, char*,
BYTE or BYTE* (unsigned char*) expect 8 bit ANSI
characters. Character conversion is performed, so the
data can be stored internally as UNICODE.
When extracting data from an mString the following
methods are of interest:
1 char *Export(char *pBuffer, const UINT
Offset = 0, const UINT NumChars = SHRT_MAX)
const;

2 WCHAR *Export(WCHAR *pBuffer, const UINT


Offset = 0, const UINT NumChars = SHRT_MAX)
const;

3 BYTE *Export(BYTE *pBuffer, const UINT


Offset = 0, const UINT NumChars = SHRT_MAX)
const;

4 char *ExportASCIIZ(char *pChar, const UINT


Offset = 0, const UINT Length = SHRT_MAX)
const;

5 WCHAR *ExportAsWCHAR(WCHAR *pChar, const


UINT Offset = 0, const UINT Length =
SHRT_MAX) const;

6 BYTE *ExportAsBytes(BYTE *pByte, UINT


NumChars = SHRT_MAX, const UINT
BytesPerChar = 1) const;

APTRA Advance ADE, Programmer’s Guide 4-13


Developing External C Functions
Designing a Function

7 TCHAR operator[](const int index) const;

Methods 1, 3, 4 and 6 will populate the target buffers


with 8-bit ANSI characters.
Methods 2, 5 and 7 will populate the target buffers with
16-bit UNICODE characters.

Methods 4, 5 and 6 are for SSDS OS/2 migration


purposes only. New code should be written using the
other methods. (Definitions for these can be found in the
MUTIL.H file.)

Note: The Operator[] method returns a TCHAR. Under


SSDS OS/2 this method returned a char. You may have
to modify your code to handle this change.

Visual C++ UNICODE support 4

Visual C++ provides functions for handling various


character sets:
● WideCharToMultiByte will convert from UNICODE
to ANSI
● MultiByteToWideChar will convert from ANSI to
UNICODE.
For more information about these functions and their
use, refer to the Microsoft Visual C++ on-line help.

4-14 APTRA Advance ADE, Programmer’s Guide


Developing External C Functions
File Locations

File Locations 4

The directory structure and the location of the


userfuns.scr user-created function registry file are shown
in Figure 4-1.

Figure 4-1
Directory Structure and Registry
4

File Location

userfuns.scr

APTRA Advance ADE, Programmer’s Guide 4-15


Developing External C Functions
File Locations

Advance ADE searches all the directories on the PATH


environment variable for the Registry File userfuns.scr.
The first file found is the one that is used. Only one user
Registry File is used each time Advance ADE is started.
After the installation of Advance ADE onto a PC, the
initial blank userfuns.scr file is located in the
<GLOBAL>\TEST\SUPPORT\USER directory.
Advance ADE searches all the directories on the PATH
command for any DLLs it requires to access. Advance
ADE will access the first DLL that has the name it is
searching for.

For each user-created external C function, a separate


User-created Function subdirectory should be created in the same area as the
Directories 4
supplied examples.
This can be done by copying an example subdirectory.
The source code (.cpp) file must be replaced by the source
code for the user-created function, and the Make (.mak)
file edited as described in “Creating a Make File” on
page 4-20.

4-16 APTRA Advance ADE, Programmer’s Guide


Developing External C Functions
Implementing a Function

Implementing a Function 4

This section explains how to implement an external C


function.

The following implementation is used when using the


General 4

Visual C++™ Release 6.0 compiler and .cpp sources. If


the function performs memory allocation you should
read “Memory Management” on page 4-18.
To use a Character Array as a parameter refer to
“Guidelines for Using a Character Array” on page 4-18.

The function must be available to be called from an


Exporting a Function Advance ADE Application. This is done by exporting the
from a DLL 4
function from the DLL by using the keyword
_declspec(dllexport).

For example, to make a function called Example, which


has no parameters, returns a double and is available to
be called from outside the DLL, use the following
declaration:

double __declspec(dllexport) Example();

To force the C++ compiler to use the C calling protocol


for external C functions, they must be declared as
extern “C”.

For the above routine the following declaration would be


required:

extern “C” double __declspec(dllexport)


Example();

APTRA Advance ADE, Programmer’s Guide 4-17


Developing External C Functions
Implementing a Function

The external C function must be registered correctly;


refer to “Registering a Function” on page 4-23 before use.

All user defined external functions should be extensively


tested before use; refer to “Testing a Function” on page
4-31.

To modify the values or change the structure of a


Guidelines for Using a character array that has been passed to the external C
Character Array 4
function, perform the following in the external function:
1 Pass the character array to the external function by
Reference.

2 Create a new character array.

3 Assign the address of the new character array to the


Reference.
For an example of this technique, refer to Chapter 5,
“Example 4: Parsing Data Using an Assigner Worker”,
page 5-16.

The Advance ADE Runtime does not free memory


Memory Management 4

passed to it by an external function.


If the external function returns allocated memory
Advance ADE Runtime makes a copy of that memory
and the Advance ADE Application uses that copy. The
memory allocated by the function is never accessed by
the Application leaving the memory free to be
deallocated at any point.
To prevent memory leakage the design of the function
should be that it retains the address of the memory it has
allocated when it is first called. Then, when it is called

4-18 APTRA Advance ADE, Programmer’s Guide


Developing External C Functions
Implementing a Function

again it can free this memory allocation before allocating


more.
When a particular process ends, the heap associated with
it is deallocated. Therefore, as long as the main function
deallocates before further allocation, any memory
leakage should be avoided.
For examples of this technique, see “Example 4: Parsing
Data Using an Assigner Worker” on page 5-16 and
“Example 5: Using External Data” on page 5-24.

APTRA Advance ADE, Programmer’s Guide 4-19


Developing External C Functions
Building a DLL

Building a DLL 4

This section describes the Microsoft™ Visual C++™


Release 6.0 Compiler build settings required to compile a
user-created external C function and to produce a Win32
Dynamic Link Library that is accessible from Advance
ADE.
The procedure for building a DLL is described in the
on-line help and documentation for the compiler.

The required project settings are as follows:


Project Settings 4

Preprocessor Definitions : STRICT


Struct Member Alignment : 1 byte
Calling convention : __cdecl *

The Make file for a user-created external C function is


Creating a Make File 4

created as follows:
1 Copy a Make (.mak) file from one of the supplied
examples into the function subdirectory; see
“User-created Function Directories” on page 4-16.

2 Rename the Make file with the same file name as the
function source code file.

3 Edit the Make file by replacing the file name of the


example with that of the user-created function

4-20 APTRA Advance ADE, Programmer’s Guide


Developing External C Functions
Building a DLL

To compile and link a user-created external C function


Build Process 4

using the Make file just created, one of the following


command lines must be used, where FunctionName is
the name of the external function:
● Debug DLLRelease DLL
nmake /f FunctionName CFG=”FunctionName -Win32 Debug”
nmake /f FunctionName CFG=”FunctionName -Win32 Releas

The location of the DLL and other output files depends


Output File Locations 4

on whether a “Debug” or “Release” version of the


function is being built.

Debug Locations 4

In the course of the compiling and linking process, a


Debug subdirectory is created in the user-created
function’s directory.
All output files other than the DLL are placed in this
directory.
The DLL is placed in <GLOBAL>\TEST\DLL. This
allows the function to be run in the Test environment on
the development PC.

Release Locations 4

In the course of the compiling and linking process, a


Release subdirectory is created in the user-created
function’s directory.
All output files including the DLL are placed in this
directory.

APTRA Advance ADE, Programmer’s Guide 4-21


Developing External C Functions
Building a DLL

If you want to use the Advance ADE Class mString then


Using the Advance you must do the following:
ADE Class mString 4

● The external C++ function must include the header


file mcore.h
● You must have the following directories on the list of
Include directories:
● Windows\Program Files\common
files\ncr\INCLUDE
● Windows\Program Files\common files\ncr\LIB
● <GLOBAL>\TEST\INCLUDE
● <GLOBAL>\TEST\LIB
● You must link with the Advance ADE Runtime
library <GLOBAL>\LIB \mcore.lib.

4-22 APTRA Advance ADE, Programmer’s Guide


Developing External C Functions
Registering a Function

Registering a Function 4

An external C function must be registered with the


Advance ADE Runtime so that it can be accessed from
an Advance ADE Application.
This registration is achieved by making a text entry in
the userfuns.scr registry file; see “File Locations” on page
4-15 for information on the location of this file.

Note: This registration is entirely the developer’s


responsibility and cannot be checked by Advance ADE
for correctness. Failure to register the function correctly
can cause unpredictable results at run-time and could
lead to system instability.

The Registration Entry must have the format shown in


the example below:
Register DLL “DLLName”
Function “FunctionName”
[Alias ”AliasName”]
Returns ReturnType
[Arguments( ArgumentTypeList )]

Note: The whole of the Registration Entry must be


made on a single line (it is shown here split into multiple
lines for clarity).

The plain text indicates parts that should be typed as


shown. The parts in square brackets are optional.
The parts in bold have to be entered by you and have the
following meanings:

APTRA Advance ADE, Programmer’s Guide 4-23


Developing External C Functions
Registering a Function

DLLName

This is the name of the DLL in which this external


function is defined. Remember the DLL name should
be in double quotes.

If Windows NT or Windows XP cannot load the DLL


the Error Loading DLL message will be displayed.
Refer to the on-line help for assistance.

FunctionName

This is the name of the function exactly as it has been


declared in the DLL. Refer to “External Function
Names” on page 4-3 for more information. Remember
the function name should be in double quotes.

If Windows NT or Windows XP cannot find the


function in the DLL, the Error Loading Function
error will occur; refer to the on-line help for assistance.

AliasName

This is optional. This allows the function to have an


alias that is used when it is called in a BASIC
Expression. Remember the alias name should be in
double quotes. Once an AliasName has been
registered, the original name cannot be used. For more
information refer to “External Function Aliases” on
page 4-4.

ReturnType

This defines the data type that is returned by the


function.

If the function does not return anything then you must


set up this part of the registration as follows:
Returns void

4-24 APTRA Advance ADE, Programmer’s Guide


Developing External C Functions
Registering a Function

For the possible values that can be entered here, refer


to the following section “Registration Entry Data
Types”.

ArgumentTypeList

This is optional. If it is not present then the function


has no arguments. If it is present, it defines a comma
separated list of data type arguments which are in the
same sequence as they appear in a BASIC Expression.
This can be a null list which means that the function
has no parameters. For the possible values that can be
entered here see the following section, “Registration
Entry Data Types”.

The following example shows the Registration Entry for


a function Example which returns an unsigned int*,
has one parameter that is a short, no alias and is defined
in a DLL called MyDLL:

Register DLL “MyDLL”


Function “Example”
Returns uinteger ByRef
Arguments( short )

Remember the entry is all on one line.

This section contains the description of what can be


Registration Entry entered for a Registration Entry Data Type.
Data Types 4

If you receive an error on entering a data type, refer to


the on-line help for assistance.
If you want to register an external data type see the
following section, “Registering External Data Types” on
page 4-28.

APTRA Advance ADE, Programmer’s Guide 4-25


Developing External C Functions
Registering a Function

There are two formats for Registration Entry Data Types.


One is for C data passing by value, and the other is for C
data passing by reference.
The first format, for passing by value, is the Registration
Keyword, as shown in Table 4-2.

Table 4-2 Registration Keyword Equivalent C/C++ Data Types


Registration Keywords and
equivalent C/C++ Types ushort unsigned short

short short

uinteger unsigned int

integer int

long long

ulong unsigned long

float float

double double

ldouble long double

uchar unsigned char

char char

string char * (ASCIIZ)

mstring mString ( Advance ADE


Class )

The second format, for passing by reference, is done by


using the Registration Keyword followed by the string
“ByRef”, which means that it is a pointer to the data
type, as shown in Table 4-3.

4-26 APTRA Advance ADE, Programmer’s Guide


Developing External C Functions
Registering a Function

Thus the Registration Entry Data Type for an unsigned


int would be as follows:

uinteger

while the entry for a pointer to an unsigned int would be:

uinteger ByRef

Table 4-3 Registration Keyword ByRef Equivalent C/C++ Data Types


Registration Keywords ByRef and
equivalent C/C++ Types ushort ByRef unsigned short *

short ByRef short *

uinteger ByRef unsigned int *

integer ByRef int *

long ByRef long *

ulong ByRef unsigned long *

float ByRef float *

double ByRef double *

ldouble ByRef long double *

uchar ByRef unsigned char *

char ByRef char *

string ByRef char ** (ASCIIZ)

mstring ByRef mString * (Advance ADE


Class)

Note: See the section on “Data Types” on page 4-7,


which mentions any restrictions on the data types that
can be used.

APTRA Advance ADE, Programmer’s Guide 4-27


Developing External C Functions
Registering a Function

When registering an external data type, the following


Registering External format must be used as its Registration Keyword:
Data Types 4

ExternalDataTypeName ByRef

where ExternalDataTypeName is the name of the


structure.
This format is used because when the function is
registered and a parameter or a return Registration
Keyword is not recognised it is assumed that it is an
external data type.
Also, as Advance ADE has no knowledge of the
structure, the external data type can only be passed by
using a reference.
For instance, if you wanted the function to return a
pointer to a structure called MyStruct then the
Registration Entry would be as follows:

Register DLL “MyDLL”


Function “Example”
Returns MyStruct ByRef
Arguments( short )

You should note that putting the name of the data type
in the Returns or the Argument expressions is important
since this is used by Advance ADE for type checking in
the external data class mHandle.

4-28 APTRA Advance ADE, Programmer’s Guide


Developing External C Functions
DLL Transfer Locations

DLL Transfer Locations 4

The location in which the user-created function DLL


should be placed for transfer to the SST depends on the
scope of the function’s applicability, as shown in Figure
4-2.

Figure 4-2
DLL Transfer Locations
4

Global
Functions

Single Application
Functions

APTRA Advance ADE, Programmer’s Guide 4-29


Developing External C Functions
DLL Transfer Locations

If the function’s applicability is specific to a single


Single Application application, the DLL should be placed in the
Functions 4
<WORKING>\MOREDLLS directory, where
<WORKING> is the application directory created by the
final build process, as described in the APTRA Advance
ADE, User’s Guide.
The function will be available only to that application.

If the function is to be made available to all applications,


Global Functions 4

the DLL should be placed in the


<GLOBAL>\FINAL\ULYSSES\MOREDLLS directory.

4-30 APTRA Advance ADE, Programmer’s Guide


Developing External C Functions
Testing a Function

Testing a Function 4

Following is a list of guidelines concerning the testing of


the external function. It is important to test external C
routines rigorously before using them in an Advance
ADE Application.

The recommended methodology for testing the new


external C function is a multistage process as follows:

The first stage of testing is done by creating a test harness


Test Harness 4

executable. This is executed outside the Advance ADE


environment, and is used to test the functionality by
loading the DLL and then executing the C function.
The test harness is built as a Windows NT or Windows
XP application which is bound to an import library
which has been created from the example DLL. The test
harness should thoroughly test all of the functionality of
the external C function.

The second stage of testing is done with the APTRA


Test Application 4

Author. A small test Application, with only a few


Workers, should be written which calls the external C
function using BASIC Expressions.
This is first used to test that the function interface,
registration and data types are correct.
To test that these are correct, some test code can be
added to the function. For instance, the following is the
code required to test the Interest function used in
Chapter 5, “External C Function Examples”.

APTRA Advance ADE, Programmer’s Guide 4-31


Developing External C Functions
Testing a Function

// Must include stdio.h for the test statements but should be removed after testing
#include <stdio.h>
:
:
extern "C" /* Prevents C++ compile mangling function name */
double /* Return data type */
__declspec(dllexport)/* Make function visible outside the DLL */
Interest( double rate, int period, double amount )
{
// open the debug file and write out parameter values
FILE * DebugFile = fopen( "\\WORKING\\DEBUG.OUT", "w" );
fprintf( DebugFile, "Rate %g Period %d Amount %g\n", Rate, Period, Amount );
:
:
//write out the result of the computation and close the file
fprintf( DebugFile, "Return %g\n", (pow((1 +( NewInterestRate/100.0 )), Period )*
Amount));
fclose( DebugFile );

return( pow( (1 + (NewInterestRate/100.0)), period ) * amount );

Once the code has been added and the function built, it is
tested by calling the function from the Test Application
with known values of rate, period and amount and
checking them against the values written to the debug.out
file.
You can also check that the return value in debug.out is
the same as the value returned to the Application.
The Visual C++™ debugger can also be used. For more
information, see Appendix B, “Debugging Your
Advance ADE Application with Visual C++™”. If you
are using mString in the external C++ function then you
will require the following type of code to write its value
to a file.

4-32 APTRA Advance ADE, Programmer’s Guide


Developing External C Functions
Testing a Function

:
// To use mString in your C++ function you must include the Advance ADE Runtime header
#include <mcore.h>
// Must include fstream.h for the test statements but should be removed after testing
#include <fstream.h>
:
:
// this is the required test code for an mString called TestString
// open debug.out
ofstream DebugOut ("\\WORKING\\DEBUG.OUT");
// get length of mString text and create buffer to hold it
unsigned int Length = TestString.GetLength();
char * Buffer = new char [ Length + 1 ];
// output the mString converted to an ASCIIZ string to debug.out and close the file
DebugOut << "mString Value ";
DebugOut << TestString.ExportASCIIZ ( Buffer, 0, Length );
DebugOut.close();
:
:

The value is written to debug.out to be compared with the


value in the Application.
The final test is done to check that the function as a
whole performs correctly when called from the small
Test Application.
Only after the extensive testing has been completed
should the external function be made available for use by
your actual Advance ADE Application.

APTRA Advance ADE, Programmer’s Guide 4-33


Developing External C Functions
Debugging a Function

Debugging a Function 4

If problems are being encountered when executing the


external function, carry out the following steps:
1 Ensure that the recommended test procedure,
described in “Testing a Function” on page 4-31, has
been performed

2 Check “Troubleshooting” on page 4-35 to see if any


information there helps with the problem

3 If this does not alleviate the problems then refer to


Appendix B, “Debugging Your Advance ADE
Application with Visual C++™”.

4-34 APTRA Advance ADE, Programmer’s Guide


Developing External C Functions
Troubleshooting

Troubleshooting 4

This section provides information about possible


problems that may occur with the external function.
If you have problems with System Escapes then you
should read the APTRA Advance ADE, User’s Guide,
which provides guidance on dealing with them.

The following is a list of problems that may occur when


Problems When running the test Application in the Author.
Running the Test
Application 4
Your external function DLL cannot be found 4

This error can occur for the following reasons:


● The directory containing your external function DLL
is not on the environment global variable PATH.
● You have put the wrong name for the DLL in the
Registration File.

Your external function name cannot be found 4

If you encounter a runtime error message saying that the


function name you have entered in the BASIC
Expression cannot be found, this means that there is a
difference between the Registration Entry and the data
that you have entered in the Author.
If the Author returns an error message saying that the
function could not be found in the DLL then the
Registration Entry is wrong.

APTRA Advance ADE, Programmer’s Guide 4-35


Developing External C Functions
Troubleshooting

Application runs in Author but gives spurious


results 4

A common cause for this is that the arguments or return


value that have been entered in the function’s
Registration Entry are incorrect. The Author does not
know what the actual function arguments are and relies
on the developer getting them right.
If you get the entry wrong, it can easily lead to spurious
data and can even cause system crashes; for instance, if
an integer value is passed where an address is expected.

4-36 APTRA Advance ADE, Programmer’s Guide


Table of Contents
External C Function Examples

Chapter 5
External C Function Examples

Overview 5-1

Introduction 5-2
File Names 5-2
File Locations 5-3

Example 1: A Calculation Using a Computer Worker 5-4


The Requirement 5-4
Designing the Function 5-5
Implementing the Function 5-6
Building the DLL 5-7
Registering the Function 5-7
Testing the Function 5-7

Example 2: Data Testing Using a Tester Worker 5-8


The Requirement 5-8
Designing the Function 5-9
Implementing the Function 5-10
Building the DLL 5-10
Registering the Function 5-11
Testing the Function 5-11

APTRA Advance ADE, Programmer’s Guide


Table of Contents
External C Function Examples

Example 3: Signal Generation Using a Selector


Worker 5-12
The Requirement 5-12
Designing the Function 5-13
Implementing the Function 5-13
Building the DLL 5-14
Registering the Function 5-15
Testing the Function 5-15

Example 4: Parsing Data Using an Assigner Worker 5-16


The Requirement 5-16
Designing the Function 5-16
Implementing the Function 5-18
Building the DLL 5-23
Registering the Function 5-23
Testing the Function 5-23

Example 5: Using External Data 5-24


The Requirement 5-24
Designing the Functions 5-25
Implementing the Functions 5-26
Building the DLL 5-31
Registering the Functions 5-31
Testing the Functions 5-31

APTRA Advance ADE, Programmer’s Guide


External C Function Examples
5

Overview

Overview 5

This chapter contains examples of the use of external C


functions.
The Introduction provides general information such as
file names and locations.
“Example 1: A Calculation Using a Computer Worker”
on page 5-4 describes an external C function which
carries out a calculation for a Computer Worker.
“Example 2: Data Testing Using a Tester Worker” on
page 5-8 describes an external C function which carries
out a test for a Tester Worker.
“Example 3: Signal Generation Using a Selector Worker”
on page 5-12 describes an external C function which is
used by a Selector Worker to produce multiple process
paths.
“Example 4: Parsing Data Using an Assigner Worker” on
page 5-16 describes an external C function which carries
out tasks required by an Assigner Worker, and provides
additional memory management information.
“Example 5: Using External Data” on page 5-24
illustrates the use of external data and memory
management by external C functions.

APTRA Advance ADE, Programmer’s Guide 5 -1


External C Function Examples
Introduction

Introduction 5

The names of the files associated with the external C


File Names 5

function examples are of the form [filename]n.[ext]


where n is the number of the example.
The files associated with each example are described in
Figure 5-1.

Table 5-1 File Type Name Description


Example File Types
Source efexamn.cpp Function source code.

Make file efexamn.mak This is used when building


the Worker Class DLL.

The output files generated from each source file will


have the same name as the source file.

5-2 APTRA Advance ADE, Programmer’s Guide


External C Function Examples
Introduction

The file locations for the external C function examples


File Locations 5

are shown in Figure 5-1.

Figure 5-1
Location of External C Function
5

Example Files

efexamn.cpp
efexamn.mak

APTRA Advance ADE, Programmer’s Guide 5-3


External C Function Examples
Example 1: A Calculation Using a Computer Worker

Example 1: A Calculation
Using a Computer Worker 5

This is an example of the use of an external C function


called from a Worker to perform a complex calculation.

The task is to calculate the accrued compound interest on


The Requirement 5

a given amount over a period and add the interest to the


initial amount to give the gross return.
This calculation has three variables, the initial amount,
the interest rate and the time period over which the
interest is to be calculated, and has a result that is the
total amount. This is given by the formula below:

TimePeriod
Total =   1 +  ---------------------------------   × InitialAmount
InterestRate
  100  

To allow the Application to make this calculation a Real


Computer Worker could be used. This type of Worker
can have any number of inputs, which it uses according
to the BASIC Expression which is one of its attributes
and returns a real value.
This could be solved with a BASIC Expression as
follows:

((1 + (InterestRate/100))^TimePeriod%)
*InitialAmount

where the variables are set up in the Parameter List


attribute of the Real computer as follows:

InterestRate,TimePeriod%,InitialAmount

5-4 APTRA Advance ADE, Programmer’s Guide


External C Function Examples
Example 1: A Calculation Using a Computer Worker

This would produce the desired result. However, now


the requirements are changed so that instead of a fixed
interest rate there is a variable rate which is based on the
initial amount with the following rules:
● If the initial amount is greater than 1000 the interest
rate is increased by 1%.
● If the initial amount is greater than 10000 the interest
rate is increased by 3%.
This extra functionality is beyond the scope of a simple
BASIC Expression, so an external C function is required.

The name of the example function is Interest. It returns


Designing the a double value which is the total amount payable at the
Function 5
end of a given period.
Since the function returns a double value it does not
have a data type suffix and does not require an alias; see
“Data Types” on page 4-6.

Defining the Interface 5

The interface with the Advance ADE Application is


defined using the BASIC Expression that was used to
calculate the compound interest. The same variables can
be used, but as parameters which are passed to the new
function, as follows:
Interest( InterestRate, TimePeriod%, InitialAmount)

APTRA Advance ADE, Programmer’s Guide 5-5


External C Function Examples
Example 1: A Calculation Using a Computer Worker

After defining the interface the next stage is to


Implementing the implement the function.
Function 5

Example Source Code 5

The program fragment below is the C source code for the


Interest function. Note the way that the function is set
up with the extern “C” and __declspec(dllexport)
keywords.

#include <math.h>

/*
Name : Interest
Description : Function to calculate total payable with compound interest
Parameters :
Rate compound interest in percent
Period time period in years
Amount initial amount
Return :
double the initial amount plus the total compound interest
*/

extern "C" /* Prevents C++ compiler mangling function name, specifies C


linkage */
double /* Return Type */
__declspec(dllexport) /* Make function visible outside the DLL.*/
Interest( double Rate, int Period, double Amount )
{
double NewInterestRate = Rate; /* Initialise new interest rate */

/* test amount for rate increase */


if( Amount > 10000 )
NewInterestRate += 3.0;
else

if( Amount > 1000 )


NewInterestRate += 1.0;

return( pow( (1 + (NewInterestRate/100.0)), Period ) * Amount );


}

5-6 APTRA Advance ADE, Programmer’s Guide


External C Function Examples
Example 1: A Calculation Using a Computer Worker

For a description on building the DLL, refer to, “Building


Building the DLL 5

a DLL” on page 4-17. Use the name “efexample1.DLL”.

Register the function in the userfuns.scr file as described


Registering the in “Registering a Function” on page 4-20, using the entry
Function 5
line shown below.

Register DLL “efexample1” Function “Interest” Returns double


Arguments(double,integer,double)

The function registers with Advance ADE and can be


executed from a BASIC Expression.

Test the function as described in “Testing a Function” on


Testing the Function 5

page 4-28.

APTRA Advance ADE, Programmer’s Guide 5-7


External C Function Examples
Example 2: Data Testing Using a Tester Worker

Example 2: Data Testing Using


a Tester Worker 5

This is an example of the use of an external C function


called from a Tester Worker to test data values.

The task is to allow an Advance ADE Application to test


The Requirement 5

whether a particular data value is within set limits. To do


this, a Tester Worker can be used. This type of Worker
can have any number of inputs, which it uses according
to the BASIC Expression which is one of its attributes. If
the result of the test is logically TRUE then the True
Signal is returned, otherwise no Signal is generated.
The advantage of a Tester not producing a Signal when
the test fails is that there may be several Testers in a
Work Group, each doing different tests. The Work
Group will return a number of TRUE Signals that can be
used to change the Application flow, but you will not
have to handle an equal number of FALSE Signals that
would otherwise be produced. In order to utilise this
characteristic, the ASYNC attribute must be set false for
all the Testers.
If all the tests fail, then there might be a requirement to
produce one FALSE Signal. Do this by placing a
PassThru Worker as the last Worker in the Work Group.
The PassThru Worker will always produce a Signal
when it is activated. But, as it is the last Worker in the
Work Group, the Work Group will only return this
Signal when none of the other Workers produce a False
signal.

5-8 APTRA Advance ADE, Programmer’s Guide


External C Function Examples
Example 2: Data Testing Using a Tester Worker

The full requirement for the Worker is that it will test an


integer value against upper and lower limits, signalling
TRUE if it is less than the upper value and greater than
the lower.

The name of the example function is WithinLimits. This


Designing the function returns an integer, which has the value 1 if the
Function 5
test is TRUE, and 0 if the test fails. It has three integer
parameters: the test value and the upper and lower
limits.
The inputs are performed using a series of input Work
Groups. Each of these Work Groups has one Worker
which supplies the value for one of the parameters. The
sequence of Input Work Groups is the same as the
sequence of parameters. If the Data Worker placed in one
of the Work Groups is not of the same data type as the
parameter then, if possible, the value will be converted
to the correct type.

Defining the Interface 5

Since the function returns a data type other than real, an


alias that incorporates a data type suffix should be used.
See “External Function Aliases” on page 4-4.
The interface with the Advance ADE Application is
defined using a BASIC Expression, as follows:

WithinLimits%( TestValue%, UpperLimit%,


LowerLimit%)

APTRA Advance ADE, Programmer’s Guide 5-9


External C Function Examples
Example 2: Data Testing Using a Tester Worker

After defining the interface the next stage is to


Implementing the implement the function.
Function 5

Example Source Code 5

The program fragment below is the C source code for the


WithinLimits function. Note the way in which the
function is set up with the extern “C” and
__declspec(dllexport) keywords.

/*
Name : WithinLimits
Description : Function to check whether value is within limits
Parameters :
TestValue value to be checked against the limits
UpperLimit to be within limits value must be less than this value
LowerLimit to be within limits value must be greater than this
value
Return :
int returns 1 if within limits, 0 otherwise
*/

extern "C" /* Prevents C++ compiler mangling function name, specifies C linkage
*/
int /* Return Type */
__declspec(dllexport) /* Make function visible outside the DLL.*/
WithinLimits( int TestValue, int UpperLimit, int LowerLimit )
{
int WithinLimitFlag = 0;

/* check within limits */


if( TestValue < UpperLimit && TestValue > LowerLimit )
WithinLimitFlag = 1;

return( WithinLimitFlag );
}

For a description on building the DLL, refer to, “Building


Building the DLL 5

a DLL” on page 4-17. Use the name “efexample1.DLL”.

5-10 APTRA Advance ADE, Programmer’s Guide


External C Function Examples
Example 2: Data Testing Using a Tester Worker

Register the function in the userfuns.scr file as described


Registering the in “Registering a Function” on page 4-20, using the entry
Function 5
line shown below. Note the use of the alias entry.

Register DLL “efexample2” Function “WithinLimits” Alias “WithinLimits%”


Returns integer Arguments(integer,integer,integer)

The function registers with Advance ADE and can be


executed from a BASIC Expression.

Test the function as described in “Testing a Function” on


Testing the Function 5

page 4-28.

APTRA Advance ADE, Programmer’s Guide 5-11


External C Function Examples
Example 3: Signal Generation Using a Selector Worker

Example 3: Signal Generation


Using a Selector Worker 5

This is an example of the use of an external C function


called from a Selector Worker to generate multiple
Signals indirectly.

The task is to allow an Application to display different


The Requirement 5

messages on the SST display depending on the month of


the year.
To allow the Application to do this test a Selector Worker
has to be used. This type of Worker has an Index Work
Group and a series of one or more Doers Work Groups.
The Index Work Group has to contain one Worker that
can give an integer, for instance an Integer Store.
The Doers Work Groups are numbered from 1 upwards
and the value returned by this Worker is used to select
the Doers Work Group to be activated.
The value of the index is ignored if it is zero or greater
than the number of Doers Work Groups.
A Selector can be used to generate Signals by putting
PassThru Workers in each of the Doers Work Groups.
The PassThru Worker activated by the particular index
value will generate a Signal. If there is an external C
function producing the index value then the function
indirectly generates Signals.

5-12 APTRA Advance ADE, Programmer’s Guide


External C Function Examples
Example 3: Signal Generation Using a Selector Worker

To accomplish the task of displaying different messages


for different months we can use an Integer Calculator
Worker; see “Example 1: A Calculation Using a
Computer Worker” on page 5-4. This will be required to
return an integer value between 1 and 12 depending on
the month of the year.

The name of the example function is GetMonth. The


Designing the function returns an integer between 1 and 12 which
Function 5
represents the month of the year and is a pointer to a tm
structure.

Defining the Interface 5

The function does not have any parameters, so the


Parameter list of the Calculator Worker is empty.
Since the function returns a data type other than real, an
alias that incorporates a data type suffix should be used.
See “External Function Aliases” on page 4-4.
The interface with the Advance ADE Application is
defined using a BASIC Expression, as follows:
GetMonth%( )

After defining the interface the next stage is to


Implementing the implement the function.
Function 5

Example Source Code 5

The program fragment below is the C source code for the


GetMonth function. Note the way in which the function
is set up with the extern “C” and
__declspec(dllexport) keywords.

This test function returns the value 1 when first called, 2


the second time, and so on until 12 is reached, at which
point it restarts the cycle with 1.

APTRA Advance ADE, Programmer’s Guide 5-13


External C Function Examples
Example 3: Signal Generation Using a Selector Worker

#include <stdlib.h>
#include <time.h>
/*
Name : GetMonth
Description : Function which returns the current month local time
Parameters :
None
Return :
int returns month as a value between 1 and 12
*/

extern "C" /* Prevents C++ compiler mangling function name, specifies C


linkage */
int /* Return Type */
__declspec(dllexport) /* Make function visible outside the DLL.*/
GetMonth( void )
{
struct tm * LocalTimePtr;
time_t Time;

/* get local time */


Time = time( NULL );

/* translate to time and date stucture */


LocalTimePtr = localtime( &Time );

#ifdef DEBUG
static int month=1;
return( ( month++ % 12 ) + 1 );
#else
/* return month */
return( LocalTimePtr->tm_mon + 1 );
#endif
}

For a description on building the DLL, refer to, “Building


Building the DLL 5

a DLL” on page 4-17. Use the name “efexample1.DLL”.

5-14 APTRA Advance ADE, Programmer’s Guide


External C Function Examples
Example 3: Signal Generation Using a Selector Worker

Register the function in the userfuns.scr file as described


Registering the in “Registering a Function” on page 4-20, using the entry
Function 5
line shown below. Note the use of the alias entry.

Register DLL “efexample3” Function “GetMonth” Alias “GetMonth%”


Returns integer

The function registers with Advance ADE and can be


executed from a BASIC Expression.

Test the function as described in “Testing a Function” on


Testing the Function 5

page 4-28.

APTRA Advance ADE, Programmer’s Guide 5-15


External C Function Examples
Example 4: Parsing Data Using an Assigner Worker

Example 4: Parsing Data Using


an Assigner Worker 5

This is an example of the use of an external C function


called from an Assigner Worker to parse a string value.

The task is to allow an Application to parse a string


The Requirement 5

containing a number of substrings separated by a


delimiter into its constituent substrings.
For example, you might want to parse the date string
“dd:mm:yyyy” into the substrings “dd”,”mm” and
“yyyy” which are the day, month and year values
respectively.
Since the routine will be modifying a character array it
will be necessary to create a new array; see “Guidelines
for Using a Character Array” on page 4-15.
An Assigner Worker can be used in an Application to
parse data. The Assigner Worker can have any number
of inputs, which it uses in accordance with its BASIC
Expression attribute to return a value.
The inputs have a corresponding series of outputs where
modified input values can be placed. A Signal is always
generated by the Assigner Worker once it has finished.

The name of the example function is Parse. The function


Designing the has two parameters called Separator and Target which
Function 5
are both null terminated strings.
The function looks for the Separator in the Target. If it is
found then a copy is made of the substring of the Target
string that occurs before the Separator and this is the

5-16 APTRA Advance ADE, Programmer’s Guide


External C Function Examples
Example 4: Parsing Data Using an Assigner Worker

return value. If it is not found then a copy is made of the


entire Target string and this is returned.
The Target string is modified by the function as follows:
if the Separator string is found then the Target string has
all the characters up to the end of the Separator substring
removed; if it is not found then all the characters are
removed from the Target string.
This methodology means that the modified Target string
can be repetitively passed to the Parse function until it is
empty and at that point the Target will have been
divided into its constituent parts.
The inputs are done using a series of input Work
Groups. Each of these Work Groups has one Worker
which supplies the value for one of the parameters. The
sequence of Input Work Groups is the same as the
sequence of parameters. If the Data Worker placed in one
of the Work Groups is not of the same data type as the
parameter then the value will be converted to the correct
type if possible.
This is also true of the outputs, which are a series of
Work Groups in the same sequence as the inputs. If no
modification is being done to the parameter, you can use
empty output Work Groups, but the sequence must be
the same as the input Work Groups.
The result of the operation is put into the Data Worker in
the Answer Work Group, translating if necessary.
So in this case the Input Work Groups will have the
Separator$ Worker in the first Work Group and the
Target$ in the second. In the Output Work Groups it will
have the first Work Group empty and the second with
the Data Worker that will receive the modified Target$

APTRA Advance ADE, Programmer’s Guide 5-17


External C Function Examples
Example 4: Parsing Data Using an Assigner Worker

String and the return value of the Parse function is put


into the Data Worker in the Answer Work Group.

Defining the Interface 5

Since the function returns a data type other than real, an


alias that incorporates a data type suffix should be used.
See “External Function Aliases” on page 4-4.
The interface with the Advance ADE Application is
defined using a BASIC Expression, as follows:
Parse$(Separator$, Target$)

After defining the interface the next stage is to


Implementing the implement the function.
Function 5

The Assigner Worker will only allow parameters to be


modified if the parameter is passed by reference.

If you put a Worker in an Output Work Group where the


corresponding parameter is not marked as ‘ByRef’ then

5-18 APTRA Advance ADE, Programmer’s Guide


External C Function Examples
Example 4: Parsing Data Using an Assigner Worker

the output Worker will contain the unmodified value of


the input Worker.

Example Source Code 5

The following program fragment is the C source code for


the Parse function. The way in which the function is set
up with the extern “C” and __declspec(dllexport)
keywords should be noted.
Note that the Target parameter is a ** char which means
that the Registration Entry is ‘string ByRef’. As noted
earlier, this method of parameter passing is required to
allow the function to modify the parameter. You should
compare this with the Separator parameter which is not
modified by the function.

Note: A new character array is allocated and its address


assigned to the Target parameter. The original data is
copied into the array before the actual parsing can occur.

To prevent memory leakage, each time it is called, the


routine should deallocate any memory allocated in a
previous call ; see “Memory Management” on page 4-15.

APTRA Advance ADE, Programmer’s Guide 5-19


External C Function Examples
Example 4: Parsing Data Using an Assigner Worker

#include <stdlib.h>
#include <string.h>

// define pointers to the new memory allocated by the Parse function

static char* ReturnString = NULL;


static char* NewTarget = NULL;

/*
Name : Parse
Description : Function checks target for separator returning the substring
found before the separator. The substring up to the end of the
separator is removed from the target
Parameters :
Separator Null terminated separator string
Target Null terminated string that is parsed.
A new Target string is created and will contain either
an empty string if the separator is not found or
the original string less the returned substring and
separator.
Return:
char * Null terminated string the result of the search, can
be entire target if separator not found in target.
*/

extern "C" /* Prevents C++ compiler mangling function name, specifies C linkage
*/

__declspec(dllexport) /* Make function visible outside the DLL.*/


char * /* Return Type */
Parse(char * Separator, char ** Target)
{
char * StringFound;
char * OriginalTarget;
int LengthOfString, StringIndex = 0;

/* free any previously allocated memory */


if (ReturnString)
{
free( ReturnString );
}
if (NewTarget)
{
free( NewTarget );
}

5-20 APTRA Advance ADE, Programmer’s Guide


External C Function Examples
Example 4: Parsing Data Using an Assigner Worker

/* since the Target string is to be modified we must allocate a new


string, copy the original string to it, and then return the address */

/* take address of original target */


OriginalTarget = *Target;

/* Create new string area and store the pointer in the static */
NewTarget = (char*) malloc( strlen(*Target) + 1);

/* Set Target to point to new memory */


*Target = NewTarget;

/* copy the original string to the new Target */


strcpy( *Target, OriginalTarget );

/* search Target for Separator */


StringFound = strstr(*Target, Separator);

/* Check if separator was found */


if(StringFound != NULL)
{
/* get length of substring found */
LengthOfString = StringFound - *Target;

/* copy the substring into the new return buffer,(calloc fills buffer
with null)*/
ReturnString = (char *) calloc(sizeof(char), LengthOfString + 1);
strncpy(ReturnString, *Target, LengthOfString);

/* move the target substring from after the separator to the start of the
target string including the null terminator */
do
{
(*Target)[StringIndex] = (*Target)[StringIndex + LengthOfString + 1];
} while((*Target)[(StringIndex++) + LengthOfString] != '\0');
}
else
{

APTRA Advance ADE, Programmer’s Guide 5-21


External C Function Examples
Example 4: Parsing Data Using an Assigner Worker

/* separator not found so copy all of the target string to the new Return
String buffer and put an empty string into the target */
ReturnString = (char *) calloc(sizeof(char), strlen(*Target)+ 1);
strcpy(ReturnString, *Target);
**Target = '\0';
}
return( ReturnString );
}

extern "C" /* Prevents C++ compiler mangling function name, specifies C linkage
*/
__declspec(dllexport) /* Make function visible outside the DLL.*/
void FreeParseMemory( void )
{
if ( ReturnString ) free( ReturnString );

if ( NewTarget )
free( NewTarget );

5-22 APTRA Advance ADE, Programmer’s Guide


External C Function Examples
Example 4: Parsing Data Using an Assigner Worker

For a description on building the DLL, refer to, “Building


Building the DLL 5

a DLL” on page 4-17. Use the name “efexample1.DLL”.

Register the function in the userfuns.scr file as described


Registering the in “Registering a Function” on page 4-20, using the entry
Function 5
line shown below. Note the use of the alias entry.

Register DLL “efexample4” Function “Parse” Alias “Parse$”


Returns string Arguments(string, string ByRef)

Test the function as described in “Testing a Function” on


Testing the Function 5

page 4-28.

APTRA Advance ADE, Programmer’s Guide 5-23


External C Function Examples
Example 5: Using External Data

Example 5: Using External


Data 5

This is an example of using an external C function to


handle external data; see “External Data Types” on page
4-8.

To illustrate the use of external data the ANSI C


The Requirement 5

structure tm (which has the time and date) will be used.


The example shows how to get the external data into an
Advance ADE Handle Store Worker, and how to
translate the tm structure held in the Handle Store
Worker into an ASCII string that can be displayed by the
Advance ADE Application.
These routines areused anywhere that a date time
structure is important; for instance, time and date
stamping a cardholder interaction.

Part 1 - Getting the tm structure 5

To allow the Application to do the first part of the task


use an Assigner Worker. Its attribute, BASIC Expression
attribute is used to call the external function; see
“Example 4: Parsing Data Using an Assigner Worker” on
page 5-16.
The Assigner always generates a Signal when it has
finished.
In this case, to get the tm structure the Input and Output
Work Groups will be empty but there will be a Handle
Store Worker in the Answer Work Group to receive the
reference to the tm structure.

5-24 APTRA Advance ADE, Programmer’s Guide


External C Function Examples
Example 5: Using External Data

Part 2 - Translating into an ASCII string 5

Use an Assigner Worker to enable the Application to


perform the second part of the task . The Assigner
Worker’s BASIC Expression attribute is used to call the
external function. In this instance, to translate the tm
structure into an ASCII string there is one Input Work
Group containing the Handle Store Worker that has the
tm structure reference. The Output Work Groups will be
empty. A String Store Worker would be in the Answer
Work Group to receive the translated string.
An Assigner Worker can be used in an Application to
parse data. The Assigner Worker can have any number
of inputs, which it uses in accordance with its BASIC
Expression attribute to return a value.

The first two functions are designed as described below.


Designing the
Functions 5
GetOurLocalTime 5

The name of the first example function is


GetOurLocalTime. This function returns a pointer to a
tm structure. It does not have any parameters, so the
Parameter list of the Assigner Worker is empty.

ConvertTimeToString 5

The name of the second example function is


ConvertTimeToString. This function returns a pointer
to a string and has one parameter which is the reference
to the tm structure.

APTRA Advance ADE, Programmer’s Guide 5-25


External C Function Examples
Example 5: Using External Data

Defining the Interfaces 5

Since the functions return pointers to data types other


than real, an alias that incorporates a data type suffix
should be used for each; see “External Function Aliases”
on page 4-4.
The interfaces with the Advance ADE Application are
defined using BASIC expressions, as follows:
GetOurLocalTime?()

and

ConvertTimeToString$(Time?)

with the Parameter list :

Time?

After defining the interfaces the next stage is to


Implementing the implement the functions.
Functions 5

All three functions required to do the complete task are


contained in the same module, but for clarity they are
shown here as separate code blocks.
To prevent memory leakage, each time the routine is
called it should deallocate any memory that was
allocated in a previous call . See “Memory Management”
on page 4-15.

Example Source Code 5

The following program fragments contain the C source


code for the GetOurLocalTime, ConvertTimeToString
and FreeTMStruct functions. Note the way in which the
functions are set up with the extern “C” and
__declspec(dllexport) keywords.

5-26 APTRA Advance ADE, Programmer’s Guide


External C Function Examples
Example 5: Using External Data

When the pointer to the tm structure is returned to the


Advance ADE Application, the Workers and functions
supplied with Advance ADE cannot manipulate this
external data since its structure is unknown. You must
create your Workers and functions to handle it.

APTRA Advance ADE, Programmer’s Guide 5-27


External C Function Examples
Example 5: Using External Data

#include <stdlib.h>
#include <time.h>
#include <string.h>
}

static struct tm* ReturnLocalTimePtr = NULL;


static char* ReturnStringPtr = NULL;

/*
Name : GetOurLocalTime
Description : Function which returns a pointer to a tm stucture which has
the current local time and date.
Parameters :
None
Return :
struct tm * returns a pointer to a tm stucture
*/

extern "C" /* Prevents C++ compiler mangling function name, specifies C linkage
*/
__declspec(dllexport) /* Make function visible outside the DLL.*/
struct tm * /* Return Type */
GetOurLocalTime( void )
{

/* Clean up any memory allocated by a previous invokation of this function */


if(ReturnLocalTimePtr)
{
free(ReturnLocalTimePtr);
}

struct tm * LocalTimePtr;
time_t Time;

/* get local time */


Time = time( NULL );

/* translate to time and date stucture */


LocalTimePtr = localtime( &Time );

5-28 APTRA Advance ADE, Programmer’s Guide


External C Function Examples
Example 5: Using External Data

py
/* get
if( memory to hold structure
ReturnLocalTimePtr */ )
!= NULL
ReturnLocalTimePtr
{ = (struct tm * ) malloc( sizeof( struct tm ) );
memcpy( ReturnLocalTimePtr, LocalTimePtr, sizeof( struct tm ));
/*
} copy time and data stucture into buffer*/
if( ReturnLocalTimePtr != NULL )
{/* return time and date pointer */
memcpy(
return( ReturnLocalTimePtr,
ReturnLocalTimePtr ); LocalTimePtr, sizeof( struct tm ));
} }

/* /* return time and date pointer */


return(
Name ReturnLocalTimePtr );
: ConvertTimeToString
} Description : Function which takes a pointer to a tm structure and which
converts to an ascii string of the following format:
/* day month date hours:minutes:seconds year\n\0
Name
Parameters :: ConvertTimeToString
Description
Time : Function Time
whichtotakes a pointer to a tm structure and which
be converted
Return : converts to an ascii string of the following format:
char * day monthreturns
date hours:minutes:seconds
a pointer to a date andyear\n\0
time string
*/ Parameters :
externTime
"C" Time toC++
/* Prevents be compiler
convertedmangling function name, specifies C linkage
*/ Return :
char *
__declspec(dllexport) /* returns a pointer
Make function to a outside
visible date andthe
time string
DLL.*/
*/
char * /* Return Type */
extern "C" /* Prevents
ConvertTimeToString(struct tm *C++ compiler mangling function name, specifies C linkage
Time)
*/
{
__declspec(dllexport) /* Make function visible outside the DLL.*/
char/** Clean up /*
anyReturn
memoryType */
allocated by a previous invokation of this function */
ConvertTimeToString(struct
if(ReturnStringPtr) tm * Time)
{ {
free(ReturnStringPtr);
/*
} Clean up any memory allocated by a previous invokation of this function */
if(ReturnStringPtr)
{char * DateTimeString ;
free(ReturnStringPtr);
}/* convert date and time to string */

char * DateTimeString
if( Time == NULL ) ;
{
/* convertreturn
date and time
"Need to string
Handle store */
in the input of Assigner" ;
}
if( Time == NULL )
{DateTimeString = asctime(Time) ;
return "Need Handle store in the input of Assigner" ;
}
DateTimeString = asctime(Time) ;

APTRA Advance ADE, Programmer’s Guide 5-29


External C Function Examples
Example 5: Using External Data

/* get memory to hold string plus one for null terminator */


ReturnStringPtr = (char *) malloc(strlen(DateTimeString) + 1);

/* copy time and data stucture into buffer*/


if(ReturnStringPtr != NULL)
{
strcpy(ReturnStringPtr, DateTimeString);
}

/* return month */
return(ReturnStringPtr);
}

extern "C"
_declspec( dllexport )
void FreeTMStruct( void )
{
if(ReturnStringPtr)
{
free( ReturnStringPtr );
}

if(ReturnLocalTimePtr)
{
free( ReturnLocalTimePtr );
}
}

5-30 APTRA Advance ADE, Programmer’s Guide


External C Function Examples
Example 5: Using External Data

For a description on building the DLL, refer to, “Building


Building the DLL 5

a DLL” on page 4-17. Use the name “efexample1.DLL”.

Register the function in the userfuns.scr file as described


Registering the in “Registering a Function” on page 4-20, using the entry
Functions 5
line shown below. Note the use of the alias entry using
the entry lines shown below. Notice the use of the alias
entry.

Register DLL “example” Function “GetOurLocalTime” Alias “GetOurLocalTime?” Returns tm


ByRef
Register DLL “example” Function “ConverTimeToString” Alias “ConvertTimeToString$”
Returns string Arguments (tm ByRef)

The function registers with Advance ADE and can be


executed from a BASIC Expression.

Test the function as described in “Testing a Function” on


Testing the Functions 5

page 4-28.

APTRA Advance ADE, Programmer’s Guide 5-31


External C Function Examples
Example 5: Using External Data

5-32 APTRA Advance ADE, Programmer’s Guide


Section 3
Advance ADE Worker Classes

Introduction Advance ADE Worker Classes-v

Chapter 6 Advance ADE Application Overview

Chapter 7 Design and Implementation Guidelines

Chapter 8 Implementation of Worker Classes

Chapter 9 Building and Testing Guidelines

Chapter 10 Advance ADE Worker Class Examples

APTRA Advance ADE, Programmer’s Guide


APTRA Advance ADE, Programmer’s Guide
Advance ADE Worker Classes
Overview

Overview

This section provides information on how to develop


user-created Advance ADE Worker Classes.
User-created Worker Classes must be written in Visual
C++™ Release 5.0 or above. All code examples in this
section are written for this compiler.
Chapter 6, “Advance ADE Application Overview”
contains a short description of how an Advance ADE
application works.
Chapter 7, “Design and Implementation Guidelines”
provides guidance for development of Advance ADE
Worker Classes.
Chapter 8, “Implementation of Worker Classes” gives
detailed information on developing and implementing
certain types of Advance ADE Worker Class.
Chapter 9, “Building and Testing Guidelines” describes
how to build and test user-created Advance ADE
Worker Classes.
Chapter 10, “Advance ADE Worker Class Examples”
describes the example Worker Classes which are
supplied with Advance ADE.

APTRA Advance ADE, Programmer’s Guide Section 3-iii


Section 3
Overview

Section 3-iv APTRA Advance ADE, Programmer’s Guide


Advance ADE Worker Classes
Introduction

Introduction

This section describes the development process used to


create a new Worker Class for use in an Advance ADE
application.
A user-created Worker Class can be used in an Advance
ADE application in exactly the same way as the supplied
Workers. You can use new Worker Classes for anything.
Look at the variety of the supplied Workers to get an
impression of what the Workers can do.
Check the existing workers to see if they can supply the
functionality required, whether alone or grouped, before
developing your own Worker Classes.

The recommended process for developing a new Worker


Worker Class Class is as follows:
Development Process
1 The Worker Classes are defined in the APTRA
Author.

Once a Worker Class has been defined, it can be


tested with the Simulator. This enables a process of
iterative refinement of the Worker Class’s interface to
be carried out.

2 When satisfactory class definitions have been


developed, the new Worker Classes are developed
and implemented in Visual C++™.

3 When this has been done the Worker Class is


available to be instantiated in your Advance ADE
application.

APTRA Advance ADE, Programmer’s Guide Section 3-v


Section 3
Introduction

The following is a numbered list of the Worker Class


Overview of development stages, where each stage is also the name of
Development Stages a section in the following chapters.
Each of the stages has a diagram associated with it which
shows the tools you use, and what is produced in the
stage.
1 “Designing a Worker Class” on page 7-2.

Editor Author Worker Class Definition

2 “Adding a Worker Class to the Advance ADE


Runtime” on page 9-5.
Author Worker Class Definition Author

New Worker Class

3 “Implementing a Worker Class” on page 7-23.

Visual C++™ IDE Worker Class source code


Worker Class header

You will need to read one of the following sections


on implementation dependent on what type of
Worker Class you are going to develop. This is
defined in stage 1 of the development process.

Section 3-vi APTRA Advance ADE, Programmer’s Guide


Section 3
Introduction

● “Implementing an Abstract Worker Class” on


page 8-2.
● “Implementing a Doer Loner” on page 8-3
● “Implementing a Getter Loner” on page 8-26
● “Implementing a Putter Loner” on page 8-32.
● “Implementing a Doer Coordinator” on page
8-38
● “Implementing a Getter Coordinator” on page
8-47
● “Implementing a Putter Coordinator” on page
8-49

4 “Building a Worker Class” on page 9-3.

Visual C++™ Worker Class source files


IDE +
Worker Class make file

Worker Class DLL Visual C++™ Linker


and Compiler

5 “Testing a Worker Class” on page 9-9.

APTRA Advance ADE, Programmer’s Guide Section 3-vii


Section 3
Introduction

Worker Class Examples 0

Chapter 10, “Advance ADE Worker Class Examples”


contains information on the example Worker Classes
which are supplied with Advance ADE.

Section 3-viii APTRA Advance ADE, Programmer’s Guide


Table of Contents
Advance ADE Application Overview

Chapter 6
Advance ADE Application
Overview

Overview 6-1

Advance ADE Application Basics 6-2


Flow of Control 6-2
Control Messages 6-3
Advance ADE Worker Class Names 6-5
Data Messages 6-5

APTRA Advance ADE, Programmer’s Guide


Table of Contents
Advance ADE Application Overview

APTRA Advance ADE, Programmer’s Guide


Advance ADE Application Overview
6

Overview

Overview 6

This chapter contains a description of the basic


functionality of an Advance ADE application and the
messages your Worker Class can handle.

APTRA Advance ADE, Programmer’s Guide 6 -1


Advance ADE Application Overview
Advance ADE Application Basics

Advance ADE Application


Basics 6

An Advance ADE application consists of a hierarchy of


Workers, with a Top Worker at the top level and Loner
Workers at the bottom.
Typically the Top Worker is a Director, although any
Doer, even a Loner, can be a Top Worker.
When an application is invoked it instantiates all of its
Workers, Work Groups and other components to create
the Worker hierarchy.

The Top Worker controls the Worker hierarchy by


Flow of Control 6

sending Control Messages to its Subworkers.


First it sends the BroadcastStart message to its Doer
Work Groups, if it has any, to activate all the
Coordinators and Subworkers that need to be activated.
The hierarchy of active Workers is called the activation
hierarchy.
A Top Worker passes an Event to its Subworkers by
sending the BroadcastEvent message to its Doer Work
Groups. As each of the active Subworkers is processing
the Event it is possible for them to generate a Signal
which is returned back up the activation hierarchy.
A Top Worker deactivates some of its Subworkers be
sending the BroadcastStop message to its Doer Work
Groups. All the Subworkers that receive this message
deactivate and any Signal they produce is returned up
the activation hierarchy. For more information, see
“Control Messages” on page 6-3.

6-2 APTRA Advance ADE, Programmer’s Guide


Advance ADE Application Overview
Advance ADE Application Basics

Workers in the Application transfer data by sending


Data Messages to one another; see “Data Messages” on
page 6-5.
The following diagram shows the Control Messages
flowing down the Worker Hierarchy and the Signals
flowing in the opposite direction. In the figure D is for
Doer and C is for Coordinator.

Figure 6-1 Control Message


Advance ADE Control Messages
6
C
Signal
and Signals

D D

C C

C D

This section contains a description of the control Do


Control Messages 6

Messages: BroadcastStart, BroadcastEvent and


BroadcastStop. These messages are responsible for the
control and execution of the Doers in the Advance ADE
application.

APTRA Advance ADE, Programmer’s Guide 6-3


Advance ADE Application Overview
Advance ADE Application Basics

BroadcastStart Message 6

The BroadcastStart message is sent by a Coordinator to


any of its Doer Work Groups that it wants to activate. All
the Workers in the Doer Work Group are activated
sequentially starting with the first Work Group. If any of
them are Coordinators themselves they send a
BroadcastStart message to their Doer, and so on, until all
the Workers in the particular activation hierarchy have
been activated.

BroadcastEvent Message 6

The BroadcastEvent message is sent by the Top Worker


when it finds an Event has occurred in the system. The
message is sent by the Top Worker to all of its active
Doer Work Groups, to allow the Subworkers to process
the Event that has occurred. If an active Doer Work
Group contains Coordinators, they in turn pass the
Event to all their active Doer Work Groups, and so on,
until all the active Workers have received the
ProcessEvent message and the associated Event.
After processing the Event, if a worker wants to indicate
that its task is complete or an error has occurred, it sends
a Signal to its Coordinator. The Signal is passed up the
worker hierarchy of Doer Work Groups.

BroadcastStop Message 6

The BroadcastStop message is sent by a Coordinator to


any of its active Doer Work Groups that it wants to
deactivate. All the Workers in the Doer Work Group are
deactivated sequentially. If any of them are Coordinators
themselves, they send a BroadcastStop message to their
Doer Work Groups, and so on, until all the Workers in
the particular activation hierarchy have been
deactivated.

6-4 APTRA Advance ADE, Programmer’s Guide


Advance ADE Application Overview
Advance ADE Application Basics

The following information applies to the supplied


Advance ADE Worker Advance ADE Worker Classes.
Class Names 6

Classes with Class Names of the form “...Giver”, for


example “StringGiver”, have Class Identifiers (IDs)of the
form “...Getter”, for example “mStringGetter”.
Classes with Class Names of the form “...Receiver”, for
example “StringReceiver”, have Class Identifiers of the
form “...Putter”, for example “mStringPutter”.
All references to the Class IDs “Getter” or “Putter”
should be read as references to the corresponding Class
Names “Giver” and “Receiver”.
For a list of Worker Class Names and IDs see APTRA
Advance ADE, C++ Class Reference, Appendix C,
“Advance ADE Class Names and Identifiers”.

This section contains a description of the Data Messages


Data Messages 6

Get and Put, which are responsible for the movement of


data in your Advance ADE application.
In the following figures, Data Message Flow is shown by
black arrows, and the associated data flow by hatched
arrows. G represents Getter, P is for Putter and C is for
Coordinator.

APTRA Advance ADE, Programmer’s Guide 6-5


Advance ADE Application Overview
Advance ADE Application Basics

Get Message 6

The Get Message is sent by a Coordinator to get data


from a Getter Worker, as shown in Figure 6-2.

Figure 6-2 Data Message


Advance ADE Get Data Message
6
C
Data Flow

Put Message 6

The Put Message is sent by a Coordinator which wants to


give data to a Putter Worker, as shown in Figure 6-3.

Figure 6-3 Data Message


Advance ADE Put Data Message
6
C
Data Flow

6-6 APTRA Advance ADE, Programmer’s Guide


Table of Contents
Design and Implementation Guidelines

Chapter 7
Design and Implementation
Guidelines

Overview 7-1

Designing a Worker Class 7-2


Worker Class Concurrency 7-3
Advance ADE Metaclasses 7-3
Worker Class Design Process 7-5
Defining Literal Types 7-19

Implementing a Worker Class 7-23


Implementation Guidelines 7-23

Implementing Attributes 7-25


Example of Attribute Implementation 7-27

APTRA Advance ADE, Programmer’s Guide


Table of Contents
Design and Implementation Guidelines

APTRA Advance ADE, Programmer’s Guide


Design and Implementation Guidelines
7

Overview

Overview 7

This chapter provides information on how to develop


user-created Advance ADE Worker Classes.
User-created Worker Classes must be written in Visual
C++™. All code examples in this section are written for
Release 6.0 of this compiler.

APTRA Advance ADE, Programmer’s Guide 7 -1


Design and Implementation Guidelines
Designing a Worker Class

Designing a Worker Class 7

This section describes the first stage in the development


of a new Worker Class, that is the designing of the
Author Worker Class Definition.
The Author Worker Class Definition is defined as the
information you must enter into the APTRA Author in
order to define your Worker Class.
The Worker Class design process has been broken down
into a series of stages. These stages are enumerated, and
we recommend you perform them in their correct
sequence.
One of the major design decisions you must make is
whether your Worker Class will have Work Groups, or
use Attributes.
Unlike C++ class attributes, the Attributes of Advance
ADE Worker Classes are defined as static by default, and
this property cannot be changed. Therefore, in the case
where the information will remain fixed throughout the
entire execution of an Advance ADE Application, an
Attribute is preferable. Where the information needs to
be dynamic during the execution of an application, a
Work Group is preferable.
The following Advance ADE Data Types can be
transferred:
● Handle (mHandle)
● Integer
● Real
● String (mString).

7-2 APTRA Advance ADE, Programmer’s Guide


Design and Implementation Guidelines
Designing a Worker Class

This section describes how Worker Classes can handle


Worker Class concurrency. Only Doers can handle concurrency, since
Concurrency 7
Getters and Putters cannot be activated.
Concurrency means that one instance of a Doer Worker
Class can be active in more than one Work Context at the
same time.
Thus, your Worker Class’s Start method will be called
once for each of the Worker’s Work Contexts.
This means that your Worker Class must handle having
an active Worker started again.

The Advance ADE Metaclasses are four distinct types of


Advance ADE Workers defined within the Advance ADE System.
Metaclasses 7

All Worker Classes fall into one and only one of these
types, which are listed next:

Abstract 7

This Worker Class is a C++ abstract class that cannot be


instantiated. Its purpose is to implement the
polymorphic effect by allowing common operations,
attributes and Work Groups to be inherited by its
subclasses.
For instance, from Data Entry the Front Fixed Key Loner
has the following superclasses:

Input Sensor

Front Key

Front Fixed Key

APTRA Advance ADE, Programmer’s Guide 7-3


Design and Implementation Guidelines
Designing a Worker Class

The Superclasses Input Sensor and Front Key are both


Abstract, and are used to supply very specific
functionality that helps their reusability.
For instance, Input Sensor is used to check for any key
press on the SST. Front Key narrows this to checking for
a key press only from keys on the front panel.
If the developer had combined the functionality of the
Front Key and Input Sensor together then for a Worker
Class that checks for a key press on the back panel an
entirely separate Worker Class would have been needed
that also incorporated the Input Sensor functionality.

Loner 7

This is a Worker Class that is at the bottom of a Worker


hierarchy in that it does not have any Work Groups.
The Timer Worker Class is an example of a Loner.

Sequencer 7

This is a Coordinator Worker Class that organises a


group of Work Groups in a defined sequence.
The Selector Worker Class is an example of a Sequencer.

Grapher 7

This is a Coordinator Worker Class that organises a


group of Work Groups as an interconnected network.
The Grapher supplied with the Advance ADE Runtime
is the Director Worker Class, which has all the
functionality you will require. Because of this, the
options of subclassing from the supplied Grapher, or
creating a new Grapher, are reserved by NCR.

7-4 APTRA Advance ADE, Programmer’s Guide


Design and Implementation Guidelines
Designing a Worker Class

The following is the iterated sequence you must go


Worker Class Design through to design your Worker Class.
Process 7

The Worker Class definition window is shown in Figure


7-1.

Figure 7-1
Worker Class Definition Window
7

1 Identify the Message Types your Worker Class will


support.

Remember that your Worker Class will inherit


Message Types from its Superclasses, when deciding
on what messages your Worker will support.

You can select any combination of the following


Message Types:

APTRA Advance ADE, Programmer’s Guide 7-5


Design and Implementation Guidelines
Designing a Worker Class

● Do

Supporting this message type means that your


Worker Class can be activated, deactivated,
process events and return Signals. A Worker
Class of this type is termed a Doer.

● Get

Supporting this message type means that your


Worker Class can give data. A Worker Class of
this type is termed a Getter.

● Put

Supporting this message type means that your


Worker Class can accept data. A Worker Class of
this type is termed a Putter.

Select the check boxes for the Message Types you


require. See also: mDoer, mPutter and mGetter
Worker Classes in the APTRA Advance ADE, C++
Class Reference.

2 Decide which Worker Superclasses your Worker


Class is to inherit from.

Superclasses are the parent Worker Classes that your


class inherits from. Your Worker Class can inherit
Operations (class methods), Attribute Types, Work
Group Types and Message Types from its
Superclasses; however it does not inherit Signal
Types.

Refer to the APTRA Advance ADE, C++ Class Reference


for the classes from which your class needs to inherit.

7-6 APTRA Advance ADE, Programmer’s Guide


Design and Implementation Guidelines
Designing a Worker Class

Note that in the APTRA Author the Superclasses are


entered as Worker Class Names. For information on
the equivalent Worker Class Names see “Control
Messages” on page 6-3.

Note: The mConcreteWorker Class is not a Worker


Class, so is not included in this list.

When you select a Superclass the appropriate


message types are selected automatically.

3 Identify any new Attribute Types that your Worker


Class introduces.

These attributes are only those for which you are


required to provide input.

You must also decide whether any of the inherited


attributes have to be redefined. In this case, the base
type (enumerated, string, integer, and so on) of the
Literal Type used must be unchanged from that used
in the Superclass.

The Attribute Types Name, Literal Type and


Description can be redefined when it is inherited;
however the AttributeID cannot be redefined.

APTRA Advance ADE, Programmer’s Guide 7-7


Design and Implementation Guidelines
Designing a Worker Class

The information required to define an Attribute Type


is as follows:

● Attribute Name
● Attribute ID
● Literal Type.

Attribute Name

You have to give the attribute a name that will be


used to prompt the Application developer.

Attribute ID

You have to give the attribute an ID that is used to


reference the attribute in your actual Worker Class
code.

This has a maximum length of 32 characters.

For more information concerning the attribute ID see


“Implementing Attributes” on page 7-25.

Attribute Literal Type

You have to define the Attribute’s Literal Type. The


APTRA Author uses the Literal Type to define what
type of data is required from the user to modify this
attribute and what the data limits are. This could
mean that you have to define a new Literal Type; see
“Defining Literal Types” on page 7-19. When
deciding what Literal Type to use, it should be as
intuitive as possible for the user to enter a value.

You must define the Literal Type before you use it as


an Attribute.

7-8 APTRA Advance ADE, Programmer’s Guide


Design and Implementation Guidelines
Designing a Worker Class

If the Attribute is an inherited one that has been


redefined then the base type (enumerated, string,
integer, and so on) of the Literal Type used must be
unchanged from that used in the Superclass.

The Attribute Literal Types are described in Table


7-1.

Table 7-1 Literal Type Description


Attribute Literal Types
Enumerated Simple enumerated type; equivalent
to the C enum type.
It appears in the Author as a list of
values that the user has to choose one
from.
File Reference Holds the information that is
required to access a file from your
Advance ADE application. It allows
the specification of a default
extension.
This allows the user of the Author to
enter a file name.
Float Simple floating number type;
equivalent to the C double type.
Integer Simple whole number type;
equivalent to the C long type.
Point A structure containing two integers;
allow the user of the Author to set
the position of a point on a screen
using the Point value as row and
column or ‘X’ and ‘Y’ coordinates.
String A simple character array where you
can define the maximum length.

APTRA Advance ADE, Programmer’s Guide 7-9


Design and Implementation Guidelines
Designing a Worker Class

Link Attribute Type

This is reserved for use by NCR.

Default Value

You can define a default value for the attribute which


will be displayed by the APTRA Author when it
prompts for user input.

Description

You can describe the Attribute Type in terms an


Advance ADE application developer would
understand.

4 You can identify any new Work Group Types that


will be introduced by your Worker Class.

You must also decide whether any of the inherited


Work Groups will have to be redefined.

The Work Group’s Name and other characteristics


can be redefined when it is inherited, except the
Group Type which cannot be redefined.

The definition of a Work Group Type requires the


following information:

● Group Name
● Group Type ID
● Subworker Class
● Message Types
● Signal Consumer
● Group Type Class ID
● Maximum Groups
● Minimum Subworkers

7-10 APTRA Advance ADE, Programmer’s Guide


Design and Implementation Guidelines
Designing a Worker Class

● Maximum Subworkers
● Description.

Group Name

You have to give the Work Group a name that the


application developer will use to access it in the
APTRA Author.

Group Type ID

You have to give the Work Group a Group Type ID


which is used in the implementation of the Work
Group.

This has a maximum length of 32 characters.

For more information see “Declaring the Work


Group Interface” on page 8-58.

Subworker Class

You have to define what class of Subworkers can be


placed in your Work Group.

If this is a redefined inherited Work Group then it


puts a limitation on what type of Subworkers it can
have; the Subworkers must be the same or a subclass
of the Subworker Class that was originally defined
by the Superclass that introduced the Work Group.

Note that in the APTRA Author the Subworkers are


entered as Worker Class Names.

Message Types

You must define what Message Types are supported


by this Work Group. It should describe all the
Message Types supported.

APTRA Advance ADE, Programmer’s Guide 7-11


Design and Implementation Guidelines
Designing a Worker Class

You can select any combination of the following


Message Types:

Table 7-2 Message


Description
Message Types Type

Do Supporting this message type means that


your Work Group contains Doer Workers
that can be activated, deactivated, process
events and return Signals
Get Supporting this message type means that
your Work Group contains Getter Workers
Put Supporting this message type means that
your Work Group contains Putter Workers

Signal Consumer

You must define whether this Work Group will


consume Signals or pass them up the Worker
hierarchy.

If your Work Group contains Workers that can


generate Signals (that is Doers) then you have two
choices on how the Work Group handles these
Signals.

The first choice is to allow the Signals to go up the


Worker hierarchy. This means that when your Work
Group receives a Signal from one of its Subworkers it
simply returns the Signal to its own Coordinator and
does not try to process the Signal in any way.

The second choice is for the Work Group to consume


all Signals that it gets from its Subworkers. This
means that when the Signals are passed to the Work
Group’s Coordinator it does not pass them up the

7-12 APTRA Advance ADE, Programmer’s Guide


Design and Implementation Guidelines
Designing a Worker Class

Worker hierarchy but processes the Signal itself.


Typically they initiate some action by the
Coordinator.

Group Type Class ID

You have to define the C++ class identifier of the


Work Group class. This class will always be a
subclass of the mWorkGroup class.

This has a maximum length of 32 characters.

See also: mWorkGroup Worker Classes in the


APTRA Advance ADE, C++ Class Reference.

Maximum Groups

You must decide the maximum number of this type


of Work Group that can be placed in your Worker.

Minimum Subworkers

You must decide the minimum number of


Subworkers that need to be placed in the Work
Group.

Maximum Subworkers

You must decide the maximum number of


Subworkers that can be placed in the Work Group.

Description

You should describe the Work Group Type in terms


an Advance ADE application developer will
understand.

5 Decide on the Class Name and Class ID for your new


Worker Class.

APTRA Advance ADE, Programmer’s Guide 7-13


Design and Implementation Guidelines
Designing a Worker Class

You have to define the Class Name which is the


name that is used in the APTRA Author environment
to reference your Worker Class.

You have to define the Class ID which is the actual


C++ name given to your Worker Class in your code.
This has a maximum length of 32 characters.

To avoid conflict with existing Worker Classes we


recommend that you use your own Class ID prefix;
for instance “a_myclass” or “bc_myclass”.

6 You can add a description of the behaviour of your


Worker Class.

This description is intended for the use of application


developers and should have that level of
information, not implementation details.

If you decide that a simple description is not enough,


you can add Help pages to your Worker Classes.

7 Decide whether a separate Icon is required for this


Worker Class.

The Icon is used to allow an Advance ADE developer


to get an idea of what a Worker Class does simply by
looking at the Icon in the Author.

An Advance ADE Icon is a 32 x 32 pixel 16 colour


Windows bitmap which is attached to the Worker
Class using the Author entry field.

Once the Icon has been added to the Author the


original bitmap is no longer required.

An example bitmap is to be found as part of the


Worker Class “Example 7: Simple Signaller” on page
10-4.

7-14 APTRA Advance ADE, Programmer’s Guide


Design and Implementation Guidelines
Designing a Worker Class

8 Decide if the Advance ADE Metaclass of your


Worker Class is Abstract.

If your class is an Abstract then you have completed


the definition.

You must enter your Abstract Class into the Author


if it provides Attributes or Work Groups that may be
inherited by a Worker Class or if it provides a Work
Group protocol.

An example of an Abstract class providing a Work


Group protocol is mStringGiver which provides a
protocol that allows only subclasses of mStringGiver
to be contained in a String Giver Work Group.

For implementation details see “Implementing an


Abstract Worker Class” on page 8-2.

9 Decide whether your Worker Class can handle


concurrency.

This defines whether a particular instance of your


Worker Class can handle being active in more than
one Worker Context at the one time.

Note: Typically a Worker Class is not designed to be


capable of concurrent execution with itself.

10 Decide what Signal Types, if any, are generated by


your Worker Class.

If you want your Worker to have the capability of


generating Signals then the class must support Do
Messages and your Worker Class must be a subclass
of the mDoer Worker Class.

APTRA Advance ADE, Programmer’s Guide 7-15


Design and Implementation Guidelines
Designing a Worker Class

This can be direct or indirect inheritance from


mDoer. Direct inheritance implies that mDoer is the
Superclass mentioned in the Author Worker Class
Definition while in indirect inheritance a subclass of
mDoer is mentioned. Note that the Signal Types are
not inherited.

Each of the Signals that can be generated by your


Worker must have the following information:

● Signal Name

You have to define the name which will appear


as a named Signal in the APTRA Author. Try to
make the name as intuitive as possible.

● Signal ID

You have to define an ID that is associated with


the Signal Type. This is the numeric value that is
returned by your mDoer Worker Class.

● Description

Describe the Signal Type in terms an Advance


ADE application developer would understand.

See also “mSignal” in the APTRA Advance ADE, C++


Class Reference.

11 Decide if the Advance ADE Metaclass of your


Worker Class is Loner.

If you decided that your Worker Class does not have


Work Groups, then it is a Loner and you have
completed the definition.

If your Loner is a Doer then for information on


implementing it see “Implementing a Doer Loner”
on page 8-3.

7-16 APTRA Advance ADE, Programmer’s Guide


Design and Implementation Guidelines
Designing a Worker Class

If it is a Putter see “Implementing a Putter Loner” on


page 8-32.

If it is a Getter see “Implementing a Getter Loner” on


page 8-26.

The Sequential Controller option is not available for a


Loner Worker Class.

12 Your Worker Class’s Advance ADE Metaclass is


Sequencer and you must decide whether your
Worker Class is a Sequential Controller.

If your Worker Class is to coordinate Doer


Subworkers then it is referred to as a Doer
Coordinator (which is itself a Doer).

Only a Doer Coordinator can be a sequential


controller. If it is a sequential controller and typically
it is, then it can only have one of its Doer Work
Groups active at any one time. If it is not then it can
have any number of Doer Work Groups active at the
same time.

For a description of how to implement your Doer


Coordinator see “Implementing a Doer Coordinator”
on page 8-38.

Your Doer Coordinator can also be a Getter or a


Putter Coordinator or both.

For an example of a Doer Coordinator that is also a


Getter Coordinator see the Worker Class example
“Example 4: Switcher” on page 10-5.

If you want to have a Getter, a Putter or a Doer


(except a Doer Coordinator) that is a Getter or Putter
Coordinator, or both, see the appropriate section for
implementing a Loner of this type.

APTRA Advance ADE, Programmer’s Guide 7-17


Design and Implementation Guidelines
Designing a Worker Class

If your Worker Class is to be a Putter Coordinator


then see “Implementing a Putter Coordinator” on
page 8-49.

If it is to be a Getter Coordinator then see


“Implementing a Getter Coordinator” on page 8-47.

For an example of a Doer that is also a Putter


Coordinator see the Worker Class example “Example
9: Get Date” on page 10-4.

For an example of a Doer that is also a Getter


Coordinator see the Worker Class examples
“Example 3: Date Setter” on page 10-4 and “Example
5: String Searcher” on page 10-5.

7-18 APTRA Advance ADE, Programmer’s Guide


Design and Implementation Guidelines
Designing a Worker Class

This section describes how to define new Literal Types


Defining Literal Types 7

which are used in conjunction with Attribute Types.


The APTRA Author uses the Literal Type to allow the
definition of a data type and its limits.
The Literal Type categories are:
● Enumerated
● File Reference
● Float
● Integer
● Point
● String.

The information required to define each Literal Type is


shown below. 7

Enumerated Literal Type 7

Table 7-3 Enumerated Type The name which will be used


Enumerated Literal Type Definition Name in the APTRA Author to access
Information this Enumerated Type
Description Describes the Enumerated
Type in terms an Advance
ADE application developer
would understand
Enumerated Values The enumerated names and
values

APTRA Advance ADE, Programmer’s Guide 7-19


Design and Implementation Guidelines
Designing a Worker Class

File Reference Literal Type 7

Table 7-4 File Reference The name which will be used in


File Reference Literal Type Type Name the APTRA Author to access this
Definition Information File Reference Type
Default Extension The default Windows file name
extension for this type of file.
Description Describes the File Reference Type
in terms an Advance ADE
application developer would
understand

Float Literal Type 7

Table 7-5 Float Type The name which will be used in


Float Literal Type Definition Name the APTRA Author to access this
Information Float Type
Minimum and The minimum and maximum
Maximum floating point values (inclusive) of
Values this Float Type
Number of Defines the number of significant
Significant digits after the decimal point
Decimal Places
Description Describes the Float Type in terms
an Advance ADE application
developer would understand

7-20 APTRA Advance ADE, Programmer’s Guide


Design and Implementation Guidelines
Designing a Worker Class

Integer Literal Type 7

Table 7-6 Integer Type The name which will be used in


Integer Literal Type Definition Name the APTRA Author when you
Information reference this Integer Type
Minimum and The minimum and maximum
Maximum Values integer values (inclusive) of this
Integer Type
Description Describes the Integer Type in
terms an Advance ADE
application developer would
understand

Point Literal Type 7

Table 7-7 Point Type The name which will be used in


Point Literal Type Definition Name the APTRA Author when you
Information access this Point Type
Minimum and The minimum and maximum
Maximum integer X coordinate values
X-Values (inclusive) of this Point Type
Minimum and The minimum and maximum
Maximum integer Y coordinate values
Y-Values (inclusive) of this Point Type
Description Describes the Point Type in terms
an Advance ADE application
developer would understand

APTRA Advance ADE, Programmer’s Guide 7-21


Design and Implementation Guidelines
Designing a Worker Class

String Literal Type 7

Table 7-8 String Type Name The name which will be used in
String Literal Type Definition the APTRA Author when you
Information access this String Type
Maximum Length The maximum number of
characters that the string can
contain
Description Describes the String Type in
terms an Advance ADE
application developer would
understand

7-22 APTRA Advance ADE, Programmer’s Guide


Design and Implementation Guidelines
Implementing a Worker Class

Implementing a Worker Class 7

This section contains information and guidelines for


implementation of your new Worker Class C++ source
and header.

This section contains a series of guidelines which must


Implementation be followed when creating a new Worker Class.
Guidelines 7

● All concrete Worker Classes must inherit directly or


indirectly from the mConcreteWorker Class.

See also: mConcreteWorker Class in the APTRA


Advance ADE, C++ Class Reference.

● Worker Classes must not inherit from more than one


Concrete Worker.
● An Abstract Worker Class must not inherit directly
or indirectly from mConcreteWorker.
● All Worker Classes that can produce Signals must be
defined to be directly or indirectly subclasses of the
mDoer class.

See also: mDoer Worker Class in the APTRA Advance


ADE, C++ Class Reference.

● A Worker Class can inherit from a number of Worker


Classes but care has to be taken over the possibility
of some of these classes having common bases.
● An Abstract Worker Class is made uninstantiable by
having a pure virtual method.
● You must produce a header file that includes the
class declaration to allow your class to be combined
with the Advance ADE Runtime.

APTRA Advance ADE, Programmer’s Guide 7-23


Design and Implementation Guidelines
Implementing a Worker Class

● You must export the Worker Class to make it


available to the Advance ADE Runtime.

You are required to use a statement of the form:


class __declspec(dllexport) mExampleClass;

where ExampleClass is your class name.

There is an option to export only the methods that


are required and not the entire Worker Class. This
produces smaller LIBs which speed up the build. To
do this you remove __declspec(dllexport) from
the class declaration and use the following format for
your method:
void __declspec(dllexport)
mExampleClass::Start(...){}

Note that you must export the class constructor and


destructor.

● You must include the Advance ADE Runtime


include file mcore.h in your header file.
● Maximise the use of private declarations in your
Worker Class header. This will help to prevent
conflict with the rest of the Advance ADE Runtime.
● A Worker Class should not respond to a User Event
by posting itself another User Event, as this could
cause the work group in which the worker is placed
to hang up.

7-24 APTRA Advance ADE, Programmer’s Guide


Design and Implementation Guidelines
Implementing Attributes

Implementing Attributes 7

This section contains the information you require to


allow you to implement Worker Class Attributes,
including code examples for each of the Literal Types.
To allow a user of the APTRA Author to edit your
Worker Class’s Attributes there must be a corresponding
public member method defined in your C++ Worker
Class. To declare this method you have to define first its
name and then its parameters.
To define the name of this method you must take the
Attribute ID of the Attribute Type (see the new Attribute
Type step in “Designing a Worker Class” on page 7-2),
and prefix it with “set_”. Thus if your Attribute ID was
for example “colour ”, then the editing method would
be called “set_colour ”.
To define the parameters of this method you must look
at its associated Literal Type. Each attribute has an
associated literal type, which defines the attribute’s type.
Each of these Literal Types has an equivalent C++ type
as shown in the Table 7-9, “Literal Types and C++
Equivalents” on page 7-26.
This would give, using our previous example of
“colour”, (if the attribute’s literal type was Integer) the
following public method:
void set_colour(long aColour);

Note: The name of the parameter is not important, only


the type.

One of the other properties of the Attribute that you will


have to define is its default value. This is one of the

APTRA Advance ADE, Programmer’s Guide 7-25


Design and Implementation Guidelines
Implementing Attributes

values you can define for your Attribute in the Author


Worker Class Definition. The Attribute method will not
be called if only its default value is being used by the
particular Worker Class instance. You have to initialise
the Attribute with the default value when the class is
instantiated.

Note: You have the responsibility of checking that the


default value defined in your Worker Class declaration
is the same as that defined in the Author Worker Class
Definition since the APTRA Author cannot check this for
you.

The attribute methods have no return value. The APTRA


Author assumes that they have been set correctly.
The Literal Types and their equivalent C++ types are
shown in Table 7-9.

Table 7-9 Literal Type C++ Type


Literal Types and C++ Equivalents
Integer long

Float double

Enumerated int

String mString&

Point long, long

File Reference mString&

The following is a list of additional implementation


notes for a particular type if it is required:
● Enumerated

The enumerated parameter has a minimum value of


0.

7-26 APTRA Advance ADE, Programmer’s Guide


Design and Implementation Guidelines
Implementing Attributes

For an Enumerated Attribute, no checking is done by


the APTRA Author that the definition of the enum
you have in your code is the same as that in your
Worker Class Definition. This means, if incorrect, it is
possible for your function to receive an out of range
value.

If you want to use an “ enum” type attribute you must


use an “int” in your function.

Thus a function definition of the type


“set_MyAttribute(int enumValue)” must be used.

● File Reference

This is the name of a file in the Windows NT or


Windows XP file format.

● Point

The two longs that you get as parameters represent


the X and Y Coordinates respectively, as defined in
the Point Literal Type.

This section contains a description of the implementation


Example of Attribute of a String Literal Type.
Implementation 7

The Worker Class “Example 1: Trace” on page 10-4


contains an actual code example of an Attribute
implementation.
The String Literal Type allows the APTRA Author user
to set the value of an mString Attribute. In the above
mentioned example we want to set up an example string
that can contain user names up to 100 characters long.

APTRA Advance ADE, Programmer’s Guide 7-27


Design and Implementation Guidelines
Implementing Attributes

If a base Literal Type already exists for an mString that


can have up to 100 characters then use it, otherwise
create a new one in the Author Worker Class Definition.
Next you must define the information required by the
Author to define an Attribute Type, as follows:
● Attribute Name

- User Name

● Attribute ID

- ExampleText

● Literal Type

- String

● Link Attribute

- This is reserved for use by NCR.

● Default Value

- Default String

● Description

- This Attribute can hold a user name up to 100


characters long.

The example code in “Example 1: Trace” on page 10-4,


shows an example class which would support the
example Attribute. This is not complete Worker Class
code and is simply used to illustrate what is required for
a String Literal Type.
Notice the name of the method ‘set_ExampleText’,
which uses the Attribute ID, and a parameter which is a
reference to an mString class.

7-28 APTRA Advance ADE, Programmer’s Guide


Design and Implementation Guidelines
Implementing Attributes

The class constructor initialises the Text variable with


the same value as defined to be the default in the Author
Worker Class Definition. This is because this method
will not be called by a particular instance of your Worker
Class if it is using the default value.

// This is an example class


class mExample

{
public:
Example():Text(“Default String”) {};
void set_ExampleText (mString& TextString);
private:
mString Text;
}

// This is the example attribute method that sets the attribute when executed
void mExample::set_ExampleText(mString& TextString)
{
Text = TextString;
}

APTRA Advance ADE, Programmer’s Guide 7-29


Design and Implementation Guidelines
Implementing Attributes

7-30 APTRA Advance ADE, Programmer’s Guide


Table of Contents
Implementation of Worker Classes

Chapter 8
Implementation of Worker
Classes

Overview 8-1

Implementing an Abstract Worker Class 8-2

Implementing a Doer Loner 8-3


Doer Worker Types 8-4
Doer Worker Methods 8-6
Activation 8-8
Event Processing 8-13
Deactivation 8-16
Implementing a Second Thread 8-21

Implementing a Getter Loner 8-26


mStringGetter 8-28
mRealGetter 8-28
mIntegerGetter 8-29
mHandleGetter 8-29

APTRA Advance ADE, Programmer’s Guide


Table of Contents
Implementation of Worker Classes

Implementing a Putter Loner 8-32


mStringPutter 8-34
mRealPutter 8-34
mIntegerPutter 8-35
mHandlePutter 8-35

Implementing a Doer Coordinator 8-38


Activation 8-41
Event Processing 8-42
Deactivation 8-44

Implementing a Getter Coordinator 8-47

Implementing a Putter Coordinator 8-49

Implementing a Work Group 8-51


Creating a Getter or Putter Work Group Type 8-52
Creating a Doer Work Group Type 8-54
Declaring the Work Group Type 8-56
Declaring the Work Group Interface 8-58
Single Work Group Interface 8-59
Multiple Work Group Interface 8-61

APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
8

Overview

Overview 8

This chapter provides information on how to implement


user-created Advance ADE Worker Classes.
User-created Worker Classes must be written in Visual
C++™. All code examples in this section are written for
this compiler.

APTRA Advance ADE, Programmer’s Guide 8 -1


Implementation of Worker Classes
Implementing an Abstract Worker Class

Implementing an Abstract
Worker Class 8

This section explains how to implement an Abstract


Worker Class which has an Advance ADE Metaclass of
Abstract.
For more information on the general implementation
guidelines, refer to “Implementing a Worker Class” on
page 7-24 .

Note: The general implementation guidelines state that


an Abstract Worker Class must not inherit directly or
indirectly from the base class mConcreteWorker.

For an example of a Base Abstract Worker Class refer to,


“Example 10: Base String” on page 10-6.
For an example of a Loner subclass of an Abstract
Worker Class, refer to “Example 11: Convert To Upper”
on page 10-6.
All Abstract Worker Classes can have Attributes Types
since these are one of the things that a subclass will
inherit. For information about implementing Attributes
see “Implementing Attributes” on page 7-26.
These Classes can also have Work Group Types since
these are also inherited by a subclass. For information
about implementing Work Group Types, see
“Implementing a Work Group” on page 8-50.

8-2 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Doer Loner

Implementing a Doer Loner 8

This section explains how to implement a Doer Loner


Worker Class which has an Advance ADE Metaclass of
Loner.
This is an example of a typical doer, it does not cover
handling concurrency. For information on handling
concurrency, see “Worker Class Concurrency” on page
7-4.
All Doers are subclasses of the mDoer Worker Class. For
a description of this class see the APTRA Advance ADE,
C++ Class Reference.
A Doer is characterised by the ability to:
● be activated, deactivated and to process Events
● generate a Signal
● access ADI-2 to communicate with SST devices
● interface with Windows NT or Windows XP to start
process threads and set semaphores.
Since the Doer exists within the Advance ADE System,
which is a multi-tasking event driven system, any Doer
you develop must execute quickly so that the next Doer
can be executed in rapid sequence. To ensure that no
system degradation occurs your Doers execution time
must be less than a tenth of a second for each of its
stages: activation, deactivation and for each event
processed.
In order to achieve this fast execution for tasks that
would take a long time to complete, you must start a
second thread while the main thread continues the
execution of the other Workers.

APTRA Advance ADE, Programmer’s Guide 8-3


Implementation of Worker Classes
Implementing a Doer Loner

In order to support the Event driven nature of the


Advance ADE System your Doer can post User Events to
itself, from either the main process thread or a second
thread .
All Doers can have Attributes. For information about
implementing Attributes see “Implementing Attributes”
on page 7-26.
Since a Loner is not an Abstract Worker Class, you must
inherit directly or indirectly from mConcreteWorker,
and your Worker Class must be instantiable.

The following different types of Doer Worker are


Doer Worker Types 8

described in this section:


● “Simple”
● “Simple Signaller”
● “Event Signaller”
● “Multi-Thread Signaller (concurrent)”.

Simple 8

When a Simple Doer is activated, it proceeds to


completion of its task. It does not process events. When
deactivated, it does nothing. It does not generate a
Signal.
For an example of a Simple Doer, see “Example 1: Trace”
on page 10-4.

Simple Signaller 8

When a Simple Signaller is activated, it proceeds to


completion of its task and sends itself a User Event,
which it has to do since a Doer cannot produce a Signal
on activation.

8-4 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Doer Loner

While it is processing events the Simple Signaller checks


for its own User Event, generating a Signal if one is
received.
When deactivated, the Simple Signaller checks for its
own User Event being late and generates a late Signal if
one is received.
For an example of a Simple Signaller, refer to “Example
7: Simple Signaller” on page 10-4.

Event Signaller 8

When an Event Signaller is activated, a command is sent


to a device and then returns.
While an Event Signaller is processing Events, it checks
for Events from the device and generates a Signal if one
is received.
When deactivated the Event Signaller checks for any late
events from the device. If one is received, it generates a
Signal which is termed “late” as it is in response to a late
Event.
For information on using Event Signallers, see Appendix
A, “ADI-2 Interfacing”,
For an example of an Event Signaller, see ”Example 6:
Eject Card”, page 10-5.

Multi-Thread Signaller (concurrent) 8

When activated, a Multi-Thread Signaller (concurrent)


starts a subthread which carries out the Doer’s task and
returns.
When the second thread has completed its task, the
Multi-Thread Signaller (concurrent) sends a User Event
to the Doer.

APTRA Advance ADE, Programmer’s Guide 8-5


Implementation of Worker Classes
Implementing a Doer Loner

While processing events in the main process thread, the


Doer checks for its own User Event sent by the second
thread. If it receives such an Event, it generates a Signal
and stops the second thread.
When a Multi-Thread Signaller (concurrent) is
deactivated, it may stop the second thread and then
check for any late user events from the second thread.
For an example of a Multi-Thread Signaller, refer to
”Example 5: String Searcher”, page 10-5.

All of these Doer types will be subclasses of the mDoer


Doer Worker Methods 8

Worker Class.
The mDoer class has three methods, Start, Stop and
ProcessEvent, which are defined as deferred methods
and must be implemented in subclasses.
These three methods provide the essential behaviour of a
Doer. They allow a Doer to be activated, deactivated, to
process events and to signal. These routines will always
have the execution sequence of activate, process event,
and deactivate with only process events being called
more than once before deactivate is called.
An example declaration of a Doer Loner called
ExampleDoer is shown in the following code fragment.

8-6 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Doer Loner

class IMP_OR_EXP mExampleDoer :


public mDoer,
public mConcreteWorker
{
public:
mExampleDoer();
~mExampleDoer();

void Start(mEventContext * aEventContext,


mWorkContext& aExecutingContext,
mWorkContext * aForwardContext);
mSignal* Stop( mEventContext * aEventContext,
mWorkContext& aWorkContext) ;
mSignal* ProcessEvent( mEventContext * aEventContext,
mWorkContext& aWorkContext,
const mEvent * aEvent);

// here you can put the public attribute methods


};

Notice that this class is a subclass of mDoer and


mConcreteWorker.
All the methods shown are public methods and must be
re-defined. The constructor must be re-defined as public
so that the class can be instantiated. All the Doer’s
Attribute methods should also appear as declared public
in the declaration. What appears elsewhere in the class
declaration is at the discretion of the programmer. What
is shown is everything that is required for a Doer Loner
to work in the Advance ADE Runtime.

Note: The Start method is called every time a particular


Worker is activated, and care is needed in the
initialisation of data members. The Worker Class
constructors are called only once when the class is
created. The Start method is called each time your Doer
is activated.

APTRA Advance ADE, Programmer’s Guide 8-7


Implementation of Worker Classes
Implementing a Doer Loner

Note: Worker Class constructors cannot have


parameters.

The following sections describe the Doer’s behaviour.

This section contains a description of the process by


Activation 8

which your Doer Worker is activated.


The Start method which is responsible for the Activation
of your Doer cannot generate Signals but can post User
Events.
Remember when designing your Start method that it
must execute quickly (in rapid sequence), so that the next
Doer can be executed.
If the execution time required by your method is too long
then you must start a second thread to do the processing.
Your Doer’s Coordinator passes control of the main
Application thread to your Doer by calling your Doer’s
Start method. The Event Queue your Doer has to use to
post User Events on is passed as the aEventContext
parameter of the Start method.
The two other parameters of the Start method
aExecutingContext and aForwardContext are not used
by a Loner.
When your Doer has completed its activation it will
return control of the main Application thread back to its
Coordinator. This is achieved by the Doer returning
from its Start method.

8-8 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Doer Loner

There are three different types of Start method you will


have to implement dependent on what type of Doer you
are implementing, as follows:
● “Simple Doer Start Method”
● “Simple Signaller Start Method”
● “Multi-Thread Signaller Start Method”

Simple Doer Start Method 8

With this type of Doer the Start method performs the


Doer’s task and then returns.
It does not use the aEventContext parameter to post User
Events, thus ignoring all of the Start parameters.
An example of the code required for this is as follows:

void mExampleDoer::Start (mEventContext*, mWorkContext&, mWorkContext*)


{
// Your functionality in here, parameters unused
};

As you can see, you just need to add your own


functionality. Once this is complete you simply return.

Simple Signaller Start Method 8

With this type of Doer the Start method performs the


Doer’s task. Then the Doer sends a User Event to inform
itself that the task is complete. This is necessary because
the Start Method cannot general signals.
Your Doer will get this User Event when it is processed
by your Doer’s ProcessEvent method or found by your
Doer’s Stop method during its deactivation as a late
Event. In both cases your Doer can then generate a
Signal.

APTRA Advance ADE, Programmer’s Guide 8-9


Implementation of Worker Classes
Implementing a Doer Loner

An example of the code required for this is as follows:

void mExampleDoer::Start (mEventContext * aEventContext, mWorkContext&, mWorkContext*)


{
UserMsg WorkerMsg;
BOOLEAN Result;

// Your functionality in here in this case setting the Result flag.

// In this case set the worker message to indicate whether the task succeed or not
// Note the WorkerMsg can be anything you want; it is interpreted
// only by your worker
WorkerMsg.Length = 1;
WorkerMsg.Data[0] = (BYTE) Result;

// PostEvent posts the user event WorkerMsg onto the Event Queue defined by
// aEventContext. The first parameter is the "this" of this worker. When the
// user event is checked in ProcessEvent and Stop, these methods will check
// for User events from "this" worker.
aEventContext->PostEvent( (mEvent*) new mUserEvent ( this, &WorkerMsg ));
};

In the code example the mUserEvent and


mEventContext classes along with the UserMsg data
type are described in the APTRA Advance ADE, C++
Class Reference.

Note: In the example, put your functionality before the


User Event is sent.

The aEventContext which is passed as a parameter is


used to provide access to the Application Event Queue.
The created mUserEvent holds the User Message,
defined in the WorkerMsg structure, and the address of
the sender of the message, defined by the ‘this’
parameter.
Thus, when the ProcessEvent and Stop methods are
given this User Message they can check whether the

8-10 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Doer Loner

message is for them by checking that they are the same


Worker as the sender.
The data stored in the WorkerMsg can be anything you
wish to put there. This data can be read by any Worker.
Once the message has been sent the activation is
complete.

Multi-Thread Signaller Start Method 8

With this type of Doer the Start method activates a


second process thread. This second thread performs the
Doer’s task and then sends a User Event to the main
Application queue to inform your Doer that, for
example, the threads task is complete or an error has
occurred.
Your Doer will get this User Event when it is processed
by your Doer’s ProcessEvent method or found by your
Doer’s Stop method during its deactivation as a late
Event. In both cases your Doer can then generate a
Signal.
For a description of implementing a second thread see
“Implementing a Second Thread” on page 8-21.
An example of the code required for this is as follows:

APTRA Advance ADE, Programmer’s Guide 8-11


Implementation of Worker Classes
Implementing a Doer Loner

void mExampleDoer::Start (mEventContext * aEventContext, mWorkContext&, mWorkContext*)


{
// You require that the parameters that are passed into the thread include the
// EventContext which is needed by the thread to post user events onto,
// and the "this" is required to get access to any data members.
ExampleThreadParams.pEventContext = aEventContext;
ExampleThreadParams.pSelf = this;

// Stack size is dependent on your thread but 16K is the minimum allocation for Advance
ADE
unsigned StackSize = 16384;

// You then create a thread to perform your Doer’s task.


// The First parameter is name of the function to execute, second is ignored,
// third is the size of the stack and the fourth is a pointer to a structure
// to allow the EventContext and "this" to be passed allowing the thread access
// to instance variables, posting of user events and so on.

_beginthread(ExampleThread, StackSize, (void *) &ExampleThreadParams);


};

In the code example, the _beginthread function is


defined in the Visual C++™ Release 5.0 Runtime
Library.
In the example, the Start method first sets a flag which is
used to handle the case where your Doer is stopped
before the thread has completed its task.
The method must then set up your thread parameter
structure with two pointers. The first pointer to your
Doer using the this parameter, which will allow the
thread to access your class members. The second pointer
to the Event Context given by the aEventContext
parameter, which will allow the thread to post a User
Event to the Application’s main thread Event Queue.
This User Event will be processed by your Doer’s
ProcessEvent or Stop method.
Once the thread has been started the activation is
complete.

8-12 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Doer Loner

This section contains a description of the process by


Event Processing 8

which your Doer Worker processes events.


The ProcessEvent method which is responsible for your
Doer’s Event processing can generate Signals and can
post User Events.
Your Doer’s Coordinator passes control of the main
Application thread to your Doer by calling your Doer’s
ProcessEvent method. The Event Queue your Doer has
to use to post User Events on is passed as the
aEventContext parameter of the ProcessEvent method
and the Event your Doer has to process is passed as the
aEvent parameter.
The other parameter of the ProcessEvent method,
aWorkingContext is not used by a Loner but simply
passed on to the EventDefault method.
When an Event is not recognised by your ProcessEvent
method it must be passed to the EventDefault method. If
it is recognised then it must not be passed to the
EventDefault method. What the default Event handler
does with the Event is reserved by NCR.
When your Doer has completed its Event processing it
will return control of the main Application thread back
to its Coordinator. This is achieved by the Doer returning
from its ProcessEvent method.
There are three different types of ProcessEvent methods
you will have to implement dependent on what type of
Doer you are implementing, as follows:
● “Simple Doer ProcessEvent Method”
● “Simple Signaller ProcessEvent Method”
● “Multi-Thread Signaller ProcessEvent Method”.

APTRA Advance ADE, Programmer’s Guide 8-13


Implementation of Worker Classes
Implementing a Doer Loner

Simple Doer ProcessEvent Method 8

With this type of Doer the ProcessEvent method does


nothing but pass any Events it receives onto the default
Event handler (since none of the events are its User
Events), and then returns any Signal that the handler
generates.
An example of the code required for this is as follows:

mSignal * mExampleDoer::ProcessEvent(mEventContext * aEventContext,


mWorkContext& aWorkContext,
const mEvent * aEvent)
{
// The event is passed to the default event handler and any signal generated is
// returned.
return(EventDefault(aEventContext, aWorkContext, aEvent));
};

As you can see from the code example, you are not
required to do anything except to pass the parameters to
the default Event handler and return any Signal it
generates.

Simple Signaller ProcessEvent Method 8

With this type of Doer, the ProcessEvent method first


checks whether the Event to be processed is a User
Event, and then whether it was sent by the Doer itself.
If the Event passes these tests, then the Event is
processed, with a Signal being generated if required. If
the Event was not meant for this Doer, it is passed onto
the default Event handler, and any Signals that the
handler generates are returned.
An example of the code required for this is as follows:

8-14 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Doer Loner

// Define Signal ID
enum SignalIds {SUCCESS = 1};

Signal * mExampleDoer::ProcessEvent(mEventContext * aEventContext,


mWorkContext& aWorkContext,
const mEvent * aEvent)
{
// first check if this event is a user event and then check whether it is a
// user events from "self" (i.e. this worker) and then process it
if((aEvent->IsType(mUserEvent::GetType())) &&
((((mUserEvent*)aEvent))->GetSender()==this))
{
// get message content of the user event
UserMsg * WorkerMsg = (((mUserEvent*)aEvent))->GetMsg();
BYTE MsgContent = WorkerMsg->Data[0];

// the message must be deleted by the worker who it was destined for but
// the user event must not be deleted.
delete WorkerMsg;

// this section of the method must be used to decide what signal is to


// returned dependent on the message recieved.
// In this example only one message can be recieved and thus only one signal
// can be returned.
return new mSignal(this, aWorkContext, SUCCESS, InternalEventPriority);

}
// Any other unrecognised event is passed to the default event handler and any
// signal generated is returned.
return( EventDefault(aEventContext, aWorkContext, aEvent);
};

In the code example, the mUserEvent, mEventContext


and mSignal classes, along with the UserMsg data type,
are described in the APTRA Advance ADE, C++ Class
Reference.
The received mUserEvent holds the User Message,
defined in the WorkerMsg structure, and the address of
the sender of the message, defined by the ‘this’
parameter.

APTRA Advance ADE, Programmer’s Guide 8-15


Implementation of Worker Classes
Implementing a Doer Loner

It is the responsibility of the Doer for which the


mUserEvent was destined to delete the WorkerMsg once
it has been used. However, it must not delete or dispose
of the mUserEvent.
This type of Doer takes the User Event and extracts the
User Message. This message could be that the task has
been completed or an error has occurred. It is your
responsibility to decide what the particular message
means.
A Signal must be returned to enable the Advance ADE
application to decide how to proceed. This Signal is an
instance of the mSignal class.
The first two parameters are always given the values
‘this’ and the Work Context respectively. The third
parameter is the Signal ID as defined in the Worker Class
Design Process, and the last parameter is the Signal
Priority.
Make sure that the value of the Signal ID you have in
your code is the same as you have defined in the APTRA
Author.
For a list of the possible priorities that your Signal can
have, see the APTRA Advance ADE, C++ Class Reference.
Once the Signal has been created and returned the Event
processing is complete.

Multi-Thread Signaller ProcessEvent Method 8

The ProcessEvent method for this type of Doer is the


same as described in the “Simple Signaller ProcessEvent
Method” on page 8-14.

This section contains a description of the process by


Deactivation 8

which your Doer Worker is deactivated.

8-16 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Doer Loner

The other parameter of the Stop method


aWorkingContext is not used by a Loner.

The Stop method which is responsible for your Doer’s


deactivation can generate late Signals.

Signals are termed ‘late’ when they are returned by the


Stop method.

Your Doer’s Coordinator passes control of the main


Application thread to your Doer by calling your Doer’s
Stop method. The Event Queue your Doer has to use to
get User Events from is passed as the aEventContext
parameter of the Stop method (although it is very
unlikely that your Stop method will post a User Event).
The other parameter of the Stop method
aWorkingContext is not used by a Loner.

The Stop method never invokes the default Event


handler whether an Event is recognised or not. Thus the
EventDefault method is never called.
When your Doer has completed its deactivation it will
return control of the main Application thread back to its
Coordinator. This is achieved by the Doer returning
from its Stop method.
There are three different types of Stop method you will
have to implement dependent on what type of Doer you
are implementing, as follows:
● “Simple Doer Stop Method”
● “Simple Signaller Stop Method”
● “Multi-Thread Signaller Stop Method”.

APTRA Advance ADE, Programmer’s Guide 8-17


Implementation of Worker Classes
Implementing a Doer Loner

Simple Doer Stop Method 8

With this type of Doer the Stop method does nothing


except return a NULL Signal. It does not check for late
events since it does not generate any User Events.
An example of the code required for this is as follows:

mSignal * mExampleDoer::Stop(mEventContext * aEventContext,


mWorkContext& aWorkContext )
{
// return a NULL signal
return (NULL); // no signal produced;
};

As you can see from the code example you are not
required to do anything except return a NULL Signal
once this has been done your Doer is deactivated.

Simple Signaller Stop Method 8

With this type of Doer, the Stop method checks for a late
User Event destined for itself from the Event Queue.
If there is a User Event it is processed, with a late Signal
being generated if required. If there is no late Event, a
NULL Signal is returned.
An example of the code required for this is as follows:

8-18 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Doer Loner

// Define Signal ID
enum SignalIds {SUCCESS = 1};
mSignal * mExampleDoer::Stop(mEventContext * aEventContext,
mWorkContext& aWorkContext )
{
// get any user event meant for this Doer from event queue
mUserEvent* aUserEvent = aEventContext->GetUserEvent(this);

// check whether a late event exists and if so process it


if (aUserEvent != NULL)
{
// get message content of the user event
UserMsg * WorkerMsg = (((mUserEvent*)aUserEvent))->GetMsg();
BYTE MsgContent = WorkerMsg->Data[0];

// the message must be deleted by the worker who retrieved it.


delete WorkerMsg;

// dispose of the User Event since it was meant for this Worker Class
// User Events should never be deleted only disposed of.
aEventContext->DisposeEvent(aUserEvent);

// this section of the method must be used to decide what signal is to


// be returned dependent on the message recieved.
// In this example ony one message can be recieved and thus only one signal
// can be returned.
return new mSignal(this, aWorkContext, 1, InternalEventPriority);
}
// If no late event then return a NULL signal
return( NULL );
};

In the code example, the mUserEvent, mEventContext


and mSignal classes along with the UserMsg data type
are described in the APTRA Advance ADE, C++ Class
Reference.
The mUserEvent retrieved holds the User Message,
defined in the WorkerMsg structure, and the address of
the sender of the message, defined by the ‘this’
parameter.

APTRA Advance ADE, Programmer’s Guide 8-19


Implementation of Worker Classes
Implementing a Doer Loner

It is the responsibility of the Doer that retrieved the


mUserEvent to delete the WorkerMsg and dispose of the
mUserEvent once it has been used.
The mUserEvent must always be disposed of (using the
Event Context’s DisposeEvent method) and never
deleted.
This type of Doer must take the late User Event and
extract the User Message. This message could be that the
task has been completed or an error has occurred. It is
your responsibility to decide what the particular
message means.
A Signal must be returned to enable the Advance ADE
application to decide how to proceed. This Signal is an
instance of the mSignal class.
The first two parameters are always given the values
‘this’ and the Work Context respectively. However the
third parameter is the Signal ID as defined in the Worker
Class Design Process and the last parameter is the Signal
Priority.
Make sure that the value of the Signal ID you have in
your code is the same as you have defined in the APTRA
Author.
The priority given to your Signal is typically (as in the
example) InternalEventPriority; see the APTRA Advance
ADE, C++ Class Reference for a list of the possible
priorities.
Once the late Signal has been created and returned the
deactivation is complete.

8-20 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Doer Loner

Multi-Thread Signaller Stop Method 8

The Stop method for this type of Doer is the same as


described in the “Simple Signaller Stop Method” on page
8-18.

This section contains a description of how to implement


Implementing a a second thread.
Second Thread 8

The second thread is started during the activation


sequence of a Multi-Thread Doer; see “Activation” on
page 8-8 for details of how the thread is activated.
The second thread is activated to carry out the main task
of your doer while the main process thread executes the
other workers in the application.
The second thread must have a minimum stack size of
16K to work correctly in the Advance ADE Runtime.
When your thread has completed its task, or it has
aborted for any reason, it should send a User Event with
the address of your Doer as the sender (so that your Doer
will recognise it as one of its own User Events and
process it). The thread should then exit.

Your Doer’s ProcessEvent or Stop method will get any


User Event that the thread has posted. However, if the
message is posted after your Doer has been deactivated,
the User Event will not be taken off the main process
Event Queue. It is then possible when you reactivate
your Worker that it will get this Event from a previous
activation. One way of handling this is to clear the queue
of any previous User Events in your Start method, before
you start posting any new ones.

APTRA Advance ADE, Programmer’s Guide 8-21


Implementation of Worker Classes
Implementing a Doer Loner

The code on the next page is an example of the


declaration of a function that executes as a second thread
within a Doer’s class declaration.

Note: The ExampleThread function is defined as a


friend function, to give it access to the class members. It
also uses the _cdecl calling convention, so that it can be
started by the _beginthread function.

Also defined in the code is the thread parameter


structure ExampleThreadParams which is passed to the
ExampleThread method by the _beginthread function
which gets it as one of its parameters. This structure is
initialised by the Doer that is creating the thread.
It contains a pointer to the Event Context that the Doer
which created the thread uses to get User Events from.
It also contains a pointer to the Doer which created the
thread. This allows the ExampleThread method access to
the Doer classes members, and also allows the User
Event to be properly addressed.
In the code example are mDoer, mConcreteWorker and
mEventContext classes which are described in the
APTRA Advance ADE, C++ Class Reference.

8-22 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Doer Loner

// This is the structure that contains the information which is passed to the second
// thread.
typedef struct
{
// pointer to the Event Context that can be used to post User Events to the
// Doer that activated the thread.
mEventContext * pEventContext;
// pointer to the Doer that activated the thread.
ExampleDoer * pSelf;
} ExampleThreadParams;

//mExampleDoer class
class mExampleDoer :
public mDoer,
public mConcreteWorker
{
public:
//
// In this part is all the normal public Doer Interface
//

// you define the thread function as a friend method which uses the
// _cdecl calling convention
friend void _decl ExampleThread(void * ThreadParams);
};

APTRA Advance ADE, Programmer’s Guide 8-23


Implementation of Worker Classes
Implementing a Doer Loner

The next section of code is an example of a thread


function.

void _cdecl ExampleThread(void * InputParams)


{
ExampleThreadParams * pParams = (ExampleThreadParams *) InputParams ;
UserMsg WorkerMsg;
BOOLEAN Result;

// Your functionality in here in this case setting the Result flag.

// In this case set the worker message to indicate whether the task succeed or not
// Note the WorkerMsg can be anything you want; it is interpreted
// only by your worker
WorkerMsg.Length = 1;
WorkerMsg.Data[0] = (BYTE) Result;

// Post the User Event with the message WorkerMsg onto the EventContext that is passed
// as a parameter from the Doer that created the thread.
// You do this so that the User Event is posted onto that Doer’s event queue.
// The first parameter is the pointer to the Doer that started the thread so that
// in your Doers ProcessEvent and Stop methods they will recognise as one of their
// User Events and process it.
(pParams->pEventContext)->PostEvent(
(mEvent*) new mUserEvent(pParams->pSelf,&WorkerMsg ));

In the code example, the mUserEvent and


mEventContext classes along with the UserMsg data
type are described in the APTRA Advance ADE, C++ Class
Reference.
In the example, you should put your functionality before
the User Event is sent.
The pEventContext which is passed as a parameter is
used to provide access to the Event Queue of the Doer
that created the thread.

8-24 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Doer Loner

The created mUserEvent holds the User Message,


defined in the WorkerMsg structure, and the address of
the thread creating Doer, defined by the pSelf parameter.
This addressing allows the thread creating Doer to
recognise that the message was meant for it.
When the Doer’s ProcessEvent and Stop methods are
given this User Event they can check whether the
message is for them by checking that they are the same
Worker as the sender.
The data stored in the WorkerMsg can be anything you
wish to put there. This data can be read by any Worker.
Once the message has been sent the thread exits.

APTRA Advance ADE, Programmer’s Guide 8-25


Implementation of Worker Classes
Implementing a Getter Loner

Implementing a Getter Loner 8

This section explains how to implement a Getter Loner


Worker Class which has an Advance ADE Metaclass of
Loner.
Your Getter is characterised by having the ability to give
data when it receives a Get Message. The data types
supported are:
● string
● floating point
● integer
● external.
All Getters are subclasses of the mGetter Worker Class.
For a description of this class see the APTRA Advance
ADE, C++ Class Reference.
All Getters can have Attributes. For further information
see “Implementing Attributes” on page 7-26.
Since a Loner is not an Abstract Worker Class, you must
inherit directly or indirectly from mConcreteWorker,
and your Worker Class must be instantiable.
For an example of both a Getter and a Putter, see
“Example 2: System Time” on page 10-4.
The Getter type class hierarchy is shown in Figure 8-1, on
the following page.

8-26 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Getter Loner

Figure 8-1 mGetter


Getter Class Hierarchy
8

mHandleGetter mStringGetter

mRealGetter

mIntegerGetter

The hierarchical structure of the Getter classes is


designed to support data conversions between the data
types except mHandleGetter which is the external data
type. The external data type will give an error if you try
to convert to another type.
The purpose of data conversions is that, if you create a
subclass of one of the known data types, the data it gives
will be dependent on the type of Getter Work Group it is
within.
For example, if you create a subclass of the
mIntegerGetter, and an instance of your Worker Class is
placed in an Integer Getter Work Group, this will give a
long value.

If the same instance is placed in a Real Getter Work


Group its long value will be converted and returned as a
double value.

If the same instance is placed in a String Getter Work


Group its long value will be converted and returned as
an mString representation of the value.

APTRA Advance ADE, Programmer’s Guide 8-27


Implementation of Worker Classes
Implementing a Getter Loner

Note: Superclasses cannot be put into Subclass specific


Work Groups. For example, you could not put an
mStringGetter into an Integer Getter Work Group.

These conversions will occur between any of the data


types as long as they are possible. Otherwise an error
will occur.
All of the Getter subclasses are abstract, with a protected
constructor and a pure virtual method. To implement an
instantiable class you must subclass from the particular
subclass of mGetter that is of the data type you want,
and implement the pure virtual method.
The following sections give implementation details for
each of the different types of Getter Loners.

This section describes how to implement your


mStringGetter 8

mStringGetter Loner Worker Class.


Your mStringGetter Loner Worker Class must be a
subclass of the mStringGetter and mConcreteWorker
Classes (see the APTRA Advance ADE, C++ Class
Reference).
Your subclass must implement the deferred method
GetString which is declared in the mStringGetter
Worker Class.
Your method must return an mString when called. The
other Get methods defined in the mStringGetter class
will perform conversions if it is possible.

This section describes how to implement your


mRealGetter 8

mRealGetter Loner Worker Class.

8-28 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Getter Loner

Your mRealGetter Loner Worker Class must be a


subclass of the mRealGetter and mConcreteWorker
classes (see APTRA Advance ADE, C++ Class Reference).
Your subclass must implement the function:
virtual double GetReal();

which is declared as pure virtual in the mRealGetter


Worker Class.
Your function must return a double value when called.
The other Get functions defined in the mRealGetter class
will perform conversions if it is possible (APTRA Advance
ADE, C++ Class Reference).

This section describes how to implement your


mIntegerGetter 8

mIntegerGetter Loner Worker Class.


Your mIntegerGetter Loner Worker Class must be a
subclass of the mIntegerGetter and mConcreteWorker
classes (see APTRA Advance ADE, C++ Class Reference).
Your subclass must implement the function:
virtual long GetInteger();

which is declared pure virtual in the mIntegerGetter


Worker Class.
Your function must return a long value when called. The
other Get functions defined in the mIntegerGetter class
will perform conversions if it is possible (check with the
APTRA Advance ADE, C++ Class Reference).

This section describes how to implement your


mHandleGetter 8

mHandleGetter Loner Worker Class.

APTRA Advance ADE, Programmer’s Guide 8-29


Implementation of Worker Classes
Implementing a Getter Loner

Your mHandleGetter Loner Worker Class must be a


subclass of the mHandleGetter and mConcreteWorker
classes (see APTRA Advance ADE, C++ Class Reference).
Your subclass must implement the function:
virtual mHandle GetHandle();

which is inherited from the mGetter Worker Class.


Your function must return an mHandle value when
called. The other Get functions defined in the
mHandleGetter class will generate an error if a
conversion is attempted. See the APTRA Advance ADE,
C++ Class Reference for further information.

Producing External Data for External Functions 8

It is possible for your mHandleGetter to produce a


Handle that can be passed to an external function.
For information about external functions handling
external data, see “External Data Types” on page 4-8.
When the external function returns an external data type,
the name of the data type (used when it is registered) is
used as the Handle ID.
Use this Handle ID as the ID of the mHandle you create
in your Worker Class, enabling the external function to
receive it.

8-30 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Getter Loner

Note that the function parameters are not type checked


before being passed.
This means that you can pass an incorrect mHandle to
your external function, without getting a Type
Mismatch error.

This could cause problems, since your external function


would get the wrong user structure.

APTRA Advance ADE, Programmer’s Guide 8-31


Implementation of Worker Classes
Implementing a Putter Loner

Implementing a Putter Loner 8

This section explains how to implement a Putter Loner


Worker Class which has an Advance ADE Metaclass of
Loner.
Your Putter is characterised by having the ability to
accept data when it receives a Put Message. The data
types supported are:
● string
● floating point
● integer
● external.
All Putters are subclasses of the mPutter worker class.
For a description of this class, see the APTRA Advance
ADE, C++ Class Reference.
All Putters can have Attributes. For further information
see “Implementing Attributes” on page 7-26.
Since a Loner is not an Abstract Worker Class, you must
inherit directly or indirectly from mConcreteWorker,
and your Worker Class must be instantiable.
For an example of both a Getter and a Putter, see
“Example 2: System Time” on page 10-4.
The Putter type class hierarchy is shown in Figure 8-2, on
the following page.

8-32 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Putter Loner

Figure 8-2 mPutter


mGetter
Putter Class Hierarchy
8

mHandlePutter mIntegerPutter

mRealPutter

mStringPutter

The hierarchical structure of the Putter classes is


designed to support data conversions between the data
types, except mHandlePutter which is the external data
type. The external data type will give an error if you try
to convert to another type.
The purpose of data conversions is that, if you create a
subclass of one of the known data types, the data it gives
will be dependent on the type of Getter Work Group it is
within.
For example, if you create a subclass of the
mStringPutter, and an instance of your Worker Class is
placed in an Integer Putter Work Group, it will accept a
long value converted to an mString.

If the same instance is placed in a Real Putter Work


Group it will be given a double value, which will be
converted to an mString.
If the same instance is placed in a String Putter Work
Group it will be given an mString.

Note: Superclasses cannot be put into Subclass specific


Work Groups. For example, you could not put an
mIntegerPutter into a String Putter Work Group.

APTRA Advance ADE, Programmer’s Guide 8-33


Implementation of Worker Classes
Implementing a Putter Loner

These conversions will occur between any of the data


types as long as they are possible. Otherwise an error
will occur.
All of the Putter subclasses are abstract with a protected
constructor and a pure virtual method. To implement an
instantiable class you must subclass from the particular
subclass of mPutter that is of the data type you want,
and implement the pure virtual method.
The following sections give implementation details for
each of the different types of Putter Loners.

This section describes how to implement your


mStringPutter 8

mStringPutter Loner Worker Class.


Your Loner Worker Class must be a subclass of the
mStringPutter and mConcreteWorker classes (see
APTRA Advance ADE, C++ Class Reference).
Your subclass must implement the function:
virtual void PutString(mString& aString);

which is declared as pure virtual in the mStringPutter


Worker Class.
Your function must accept an mString value when
called. The other Put functions defined in the
mStringPutter class will perform conversions if it is
possible (check with the APTRA Advance ADE, C++ Class
Reference).

This section describes how to implement your


mRealPutter 8

mRealPutter Loner Worker Class.


Your mRealPutter Loner Worker Class must be a
subclass of the mRealPutter and mConcreteWorker
classes (see APTRA Advance ADE, C++ Class Reference).

8-34 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Putter Loner

Your subclass must implement the function:


virtual void PutReal(double aReal);

which is declared as pure virtual in the mRealPutter


Worker Class.
Your function must return a double value when called.
The other Put functions defined in the mRealPutter class
will perform conversions if it is possible. See the APTRA
Advance ADE, C++ Class Reference.

This section describes how to implement your


mIntegerPutter 8

mIntegerPutter Loner Worker Class.


Your mIntegerPutter Loner Worker Class must be a
subclass of the mIntegerPutter and mConcreteWorker
classes (see APTRA Advance ADE, C++ Class Reference).
Your subclass must implement the function:
virtual void PutInteger(long anInteger);

which is declared as pure virtual in the mIntegerPutter


Worker Class.
Your function must return a long value when called. The
other Put functions defined in the mIntegerPutter class
will perform conversions if it is possible (check with the
APTRA Advance ADE, C++ Class Reference).

This section describes how to implement your


mHandlePutter 8

mHandlePutter Loner Worker Class.


Your mHandlePutter Loner Worker Class must be a
subclass of the mHandlePutter and mConcreteWorker
classes (see APTRA Advance ADE, C++ Class Reference).
Your subclass must implement the function:

APTRA Advance ADE, Programmer’s Guide 8-35


Implementation of Worker Classes
Implementing a Putter Loner

virtual void PutHandle(mHandle& handle);

which is inherited from the mPutter Worker Class.


Your function must return an mHandle value when
called. The other Put functions defined in the
mHandlePutter class will generate an error if a
conversion is attempted. See the APTRA Advance ADE,
C++ Class Reference.
For an example of a subclass of mHandlePutter, see
“Example 8: Convert Handle TM” on page 10-6.

Processing External Data from External Functions 8

It is possible for your mHandlePutter to process a


Handle generated by an external function.
For information about external functions handling
external data, see “External Data Types” on page 4-8.
When the external function returns an external data type
then the name of the data type (used when it is
registered) is used as the Handle ID.
You then have three ways of processing the Handle
dependent on which mHandle method you use as
follows:
● GetData: Form 1
● GetData: Form 2
● GetID.

GetData: Form 1 8

This form of the function checks that the Handle ID is


correct, and returns a NULL pointer if it is not.
This is a safe method of data transfer since type checking
is enabled.

8-36 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Putter Loner

If the ID in the Author is incorrect, an error is displayed.


The Worker Class example “Example 8: Convert Handle
TM” on page 10-6 is an illustration of this method where
tm is the structure being passed.

GetData: Form 2 8

This form of the function does not check that the Handle
ID is correct.
This is NOT a safe method of data transfer since type
checking is disabled.

GetID 8

In this method, the Handle ID is obtained using this


function and then compared against the one stored in
your Worker Class.
If the IDs are different then no further processing of the
mHandle is performed.
This is a safe method of data transfer since type checking
is done in the code.
No errors are displayed in the Author if the ID is
incorrect.

APTRA Advance ADE, Programmer’s Guide 8-37


Implementation of Worker Classes
Implementing a Doer Coordinator

Implementing a Doer
Coordinator 8

This section describes how to implement a Doer


Coordinator Worker Class.
All Doer Coordinators are subclasses of the mDoer class.
For a description of this class, see the APTRA Advance
ADE, C++ Class Reference.
A Doer Coordinator can coordinate any number of Doer
Work Groups with any number of Doer Subworkers.
Your Doer Coordinator can also be a Getter Coordinator
(see “Implementing a Getter Coordinator” on page 8-47)
and a Putter Coordinator see (“Implementing a Putter
Coordinator” on page 8-49).
All Doer Coordinators can have Attributes. For further
information see “Implementing Attributes” on page
7-25.
This section describes a typical Doer Coordinator, that
does not handle concurrency. See “Worker Class
Concurrency” on page 7-3 for more information.
The Worker Class “Example 4: Switcher” on page 10-5 is
an example of a Doer Coordinator.
If you want your Coordinator to be instantiable, it must
inherit directly or indirectly from mConcreteWorker.
Your Doer Coordinator is responsible for controlling a
series of Doer Work Groups and the Doer Subworkers
contained in them. The Subworkers can be Doer
Coordinators or Doer Loners. For further information,
see “Implementing a Doer Loner” on page 8-3.

8-38 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Doer Coordinator

Your Doer Coordinator is characterised by having the


ability, when activated, to activate a Doer Work Group
and its Doers.
When your Doer Coordinator processes an Event, it can
process the Event itself, or give the Event to the active
Work Group, or both. If the active Work Group gets the
Event it gives it to its Doers. These Doers can generate
Signals which the Work Group collects and then selects
one to return to its Coordinator. The exception to this is if
the Work Group Type is a Signal Consumer in which
case the Signal is used by the Coordinator (to initiate
some action) and is not returned to its Coordinator.
When your Doer Coordinator is deactivated it
deactivates the active Work Group. The Work Group
collects any late Signals from its Doer Subworkers and
then selects one to return to its Coordinator. The
exception to this is if your if the Work Group Type is a
Signal Consumer in which case the late Signal is used by
the Coordinator (to initiate some action) and is not
returned to its Coordinator.
If your Coordinator produces its own late Signal it must
compare this with the late Signal returned by the
Subworkers and return the one with the highest priority.
For your Worker Class to coordinate Doers you must
implement a Doer Work Group; see “Implementing a
Work Group” on page 8-50.
Thus, the full public declaration for your Doer
Coordinator, including the methods for adding and
removing the Doer Work Groups, will be as follows. In
this example, the Coordinator is called
mExampleDoerCoordinator, and the Work Group Type
Class ID is ExampleDoers.

APTRA Advance ADE, Programmer’s Guide 8-39


Implementation of Worker Classes
Implementing a Doer Coordinator

class IMP_OR_EXP mExampleDoerCoordinator :


public mDoer,
public mConcreteWorker
{
public:
mExampleDoer();
~mExampleDoer();

voidStart(mEventContext * aEventContext,
mWorkContext& aExecutingContext,
mWorkContext * aForwardContext);
mSignal* Stop(mEventContext * aEventContext,
mWorkContext& aWorkContext) ;
mSignal* ProcessEvent( mEventContext * aEventContext,
mWorkContext& aWorkContext,
const mEvent * aEvent);

mWorkGroup * Add_ExampleDoers_WorkGroup( unsigned short WGId );


void Remove_ExampleDoers_WorkGroup( unsigned short WGId );

// here you can put the public attribute methods


};

Your Doer Coordinator inherits three deferred methods


from the mDoer Worker Class: Start, Stop and
ProcessEvent. These must be implemented in concrete
subclasses.
The three methods provide the essential behaviour of a
Doer Coordinator. They allow your Doer Coordinator to
be activated, deactivated, give events to and get Signals
from Doer Subworkers. These methods will always have
the execution sequence of activate, process event, and
deactivate with only process events being called more
than once before deactivate is called.
Your Doer Coordinator can do its own processing and
generate its own Signals.

8-40 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Doer Coordinator

Notice that this class is a subclass of mDoer and


mConcreteWorker, which is essential for an instantiable
Coordinator Doer.
All the methods shown are the public methods that must
be redefined by you. The constructor must be defined as
public so that the class can be instantiated. All the Doer’s
Attribute methods should also appear declared public in
the declaration. The data that appears elsewhere in the
class declaration is at your discretion, since what is
shown is all that is required for a Doer Coordinator to
work in the Advance ADE Runtime.

Note: Since the Start method is called every time a


particular Worker is activated, care is needed in the
initialization of data members.

The Worker Class constructors are typically called once


when the class is loaded. The Start method is called each
time your Doer is activated.
The following sections describe each of the different
stages of the Doer Coordinator behaviour.

This section contains a description of the process by


Activation 8

which your Doer Coordinator Worker is activated.


Its Start method, ProcessEvent method and deferred
methods can all be used to activate Doer Subworkers.
Typically the ProcessEvent method is used.
Your Doer’s Coordinator passes control of the main
Application thread to your Doer by calling your Doer’s
Start method.
To activate the Subworkers the BroadcastStart method,
defined in the mTDoerWorkGroup class template, is
called. This method calls each Doer Subworker’s Start

APTRA Advance ADE, Programmer’s Guide 8-41


Implementation of Worker Classes
Implementing a Doer Coordinator

method in turn. All of the Start method’s parameters are


passed to your Doer Subworkers by the BroadcastStart
method.
This execution sequence is defined in the
mTDoerWorkGroup class, and starts with the first
Worker added, continuing until the last has been
activated.
When all your Doer Subworkers have completed their
activation your Coordinator Doer will return control of
the main Application thread back to its Coordinator.
This is achieved by the Doer returning from its Start
method.
An example of the code required for this is as follows:

void mExampleDoerCoordinator::Start(mEventContext * aEventContext,


mWorkContext& aExecutingContext,
mWorkContext * aForwardContext )
{
// ActiveDoerWorkGroup is a pointer to the Work Group to be activated if
// you have more than one Work Group in a dynamic array or list you must use
// some way to decide which one is to be executed

// Activate the Doer Work Group


ActiveDoerWorkgroup->BroadcastStart(aEventContext,
aExecutingContext,
aForwardContext);

};

As you can see from the code example, you are not
required to do anything, except pass the parameters on
to your Subworkers. However, you can add your own
code, so that the Coordinator has its own functionality.

This section contains a description of the process by


Event Processing 8

which your Doer Coordinator Worker processes events.

8-42 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Doer Coordinator

The ProcessEvent method is responsible for passing


events to your active Doer Subworkers. These
Subworkers can generate Signals and post User Events
while processing the Event.
Your Doer’s Coordinator passes control of the main
Application thread to your Doer by calling your Doer’s
ProcessEvent method.
To pass the Event to the Subworkers the BroadcastEvent
method (defined in mTDoerWorkGroup) is called. This
method calls each Doer Subworker’s ProcessEvent
method in turn. All of the ProcessEvent method’s
parameters are passed to your Doer Subworkers by the
BroadcastEvent method.
The execution sequence is the same as for the Subworker
activation.
When all your Doer Subworkers have completed their
Event processing the BroadcastEvent method will return
one Signal which has been chosen from all the Signals
generated by the Doer Subworkers. How this choice is
made is described in the APTRA Advance ADE, C++ Class
Reference.
At this point your Doer Coordinator has two choices,
depending on whether the Work Group Type is a Signal
Consumer. If it is, the Signal returned by the
BroadcastEvent method would be used by the
Coordinator to initiate some action and then deleted. The
Coordinator would return a NULL Signal. If it is not, the
Signal returned by the BroadcastEvent method is used as
the return value for your Doer’s ProcessEvent method.
Your Coordinator Doer will then return control of the
main Application thread back to its Coordinator. This is
achieved by the Doer returning from its ProcessEvent
method.

APTRA Advance ADE, Programmer’s Guide 8-43


Implementation of Worker Classes
Implementing a Doer Coordinator

An example of the code required for this is as follows:

mSignal * mExampleDoerCoordinator::ProcessEvent(mEventContext * aEventContext,


mWorkContext& aWorkContext,
const mEvent * aEvent)
{
mSignal RetSig;

// ActiveDoerWorkGroup is a pointer to the Work Group to be activated if


// you have more than one Work Group in a dynamic array or list you must use
// some way to decide which one is to be executed

// Pass the event to the active Doer Work Group


RetSig = ActiveDoerWorkgroup->BroadcastEvent( aEventContext,
aWorkContext,
aEvent);

// check whether return signal Null. If it is not return signal


// Any other unrecognised event is passed to the default event handler and any
// signal generated is returned.
if( RetSig == NULL )
return EventDefault(aEventContext, aWorkContext, aEvent;
else
return RetSig;
};

As you can see from the code example, you must test the
Signal returned by the Subworkers, and if it is NULL
pass the event to the default event handler.
Then the Signal from the Subworkers or the default
event handler should be the returned as this is not a
Signal Consumer.

This section contains a description of the process by


Deactivation 8

which your Doer Coordinator Worker is deactivated.


The Stop method is responsible for the deactivation of
the active Doer Subworkers. These Subworkers can
generate late Signals while deactivating.

8-44 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Doer Coordinator

Your Doer’s Coordinator passes control of the main


Application thread to your Doer by calling your Doer’s
Stop method.
To deactivate the Subworkers the BroadcastStop method
(defined in mTDoerWorkGroup) is called. This method
calls each Doer Subworker’s Stop method in turn. All of
the Stop method’s parameters are passed to your Doer
Subworkers by the BroadcastStop method.
The execution sequence is the same as for the Subworker
activation.
When all your Doer Subworkers have been deactivated
the BroadcastStop method may return one late Signal
which has been chosen from all the Signals generated by
the Doer Subworkers. How this choice is made is
described in the APTRA Advance ADE, C++ Class
Reference.
At this point your Doer Coordinator has two choices,
depending on whether the Work Group Type is a Signal
Consumer. If it is, the late Signal returned by the
BroadcastStop method is deleted and a NULL Signal is
returned by the Coordinator. If it is not, the Signal
returned by the BroadcastStop method is used as the
return value for your Doer’s Stop method.
Your Coordinator Doer will then return control of the
main Application thread back to its Coordinator. This is
achieved by the Doer returning from its Stop method.
An example of the code required for this is as follows:

APTRA Advance ADE, Programmer’s Guide 8-45


Implementation of Worker Classes
Implementing a Doer Coordinator

mSignal * mExampleDoerCoordinator::Stop( mEventContext * aEventContext,


mWorkContext& aWorkContext )
{
// ActiveDoerWorkGroup is a pointer to the Work Group to be deactivated if
// you have more than one Work Group in a dynamic array or list you must use
// some way to decide which one is to be executed

// Deactivate the active Doer Work Group and return a late signal
return ActiveDoerWorkgroup->BroadcastStop( aEventContext,
aWorkContext );
};

As you can see from the code example, you are not
required to do anything except pass the parameters on to
your Subworkers, and simply return any late Signal
generated since this is not a Signal Consumer.
If your Coordinator produces its own Signal it must
compare this with the late Signal returned by the
Subworkers and return the signal with the highest
priority.

8-46 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Getter Coordinator

Implementing a Getter
Coordinator 8

This section describes how to implement a Worker Class


that is a Getter Coordinator.
A Getter Coordinator can coordinate any number of
Getter Work Groups with any number of Getter
Subworkers.
Doers, Getters and Putters can all be Getter
Coordinators.
The Worker Classes “Example 3: Date Setter” on page
10-4, “Example 4: Switcher” on page 10-5, and “Example
5: String Searcher” on page 10-5 are all examples of
Getter Coordinators.
For your Worker Class to coordinate Getters you must
implement a Getter Work Group. See “Implementing a
Work Group” on page 8-51.
To get the data from your Worker Class’s Subworkers
you must first get the address of one of the Work
Group’s Subworkers.
This is done by calling the mTBasicWorkGroup template
method GetWorker. The parameter to this routine is
used as the index into the array of Getter Subworkers
contained in this Work Group. The lowest index value is
0 which is used to get the first Getter inserted into the
Work Group.
To find the number of Getters in the Work Group, the
mTBasicWorkGroup template GetNumWorkers method
can be called.

APTRA Advance ADE, Programmer’s Guide 8-47


Implementation of Worker Classes
Implementing a Getter Coordinator

Once you have the address of the Getter, you can simply
call one of the methods defined in the Getter, to get the
data in the format that you require.
Thus, the code to get the data from an mStringGetter
Subworker which is the only Subworker in a particular
Work Group would be as follows:

// This is a section of code you would require to get data from a String Getter

// StringGetterWG is a pointer to a Work Group that has been created


// to hold one String Getter Subworker
mStringGetter * StringGetterWorker;
mString Buffer;

// check if Work Group has a Subworker


if ((StringGetterWorker = ((mStringGetter *)StringGetterWG->GetWorker(0)))!= NULL)
{
// get data
Buffer = StringGetterWorker->GetString();

If you wish, you could put the data that you get from the
Subworker through a validation process.
This section of code can be used anywhere in any of the
Coordinators.

8-48 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Putter Coordinator

Implementing a Putter
Coordinator 8

This section describes how to implement a Worker Class


that is a Putter Coordinator.
A Putter Coordinator can coordinate any number of
Putter Work Groups with any number of Putter
Subworkers.
Doers and Putters can be Putter Coordinators; Getters
cannot.
For an example of a Putter Coordinator, see “Example 9:
Get Date” on page 10-4.
For your Worker Class to coordinate Putters you must
implement a Putter Work Group. See “Implementing a
Work Group” on page 8-51.
To give the data to your Worker Class’s Subworkers you
must first get the address of one of the Work Group’s
Subworkers.
This is done by calling the mTBasicWorkGroup template
method GetWorker. The parameter to this routine is
used as the index into the array of Putter Subworkers
contained in this Work Group. The lowest index value is
0 which is used to get the first Putter inserted into the
Work Group.
To find the number of Putters in the Work Group
mTBasicWorkGroup template GetNumWorkers method
can be called.

APTRA Advance ADE, Programmer’s Guide 8-49


Implementation of Worker Classes
Implementing a Putter Coordinator

Then, when you have the address of the Putter, you can
simply call one of the methods defined in the Putter to
give the data in the format that you require.
Thus, the code to give the data to a mStringPutter
Subworker which is the only Subworker in a particular
Work Group would be as follows:

// This is a section of code you would require to give data to a String Getter

// StringPutterWG is a pointer to a Work Group that has been created


// to hold one String Putter Subworker
mStringPutter * StringPutterWorker;

// check if Work Group has a Subworker


if ((StringPutterWorker = ((mStringPutter *)StringPutterWG->GetWorker(0)))!= NULL)
{
// give data to the Subworker where Buffer is an mString that contains the value
// you want to give
StringPutterWorker->PutString(Buffer);
}

This section of code can be used anywhere in any of the


Coordinators.

8-50 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Work Group

Implementing a Work Group 8

This section describes how to implement a Doer, a Getter


or a Putter Work Group Type in your Worker Class.
To implement a Work Group in your Coordinator
Worker Class you should complete the following steps:

1 Create your new Work Group Type which is


dependent on what type of Subworker you wish to
have in your Work Group.

If your Work Group is to contain Getter or Putter


Subworkers then see section “Creating a Getter or
Putter Work Group Type” on page 8-52.

If your Work Group is to contain Doer Subworkers


then see section “Creating a Doer Work Group Type”
on page 8-54.

2 Declare and initialise the pointer or array of pointers


to the new Work Group Type. See section “Declaring
the Work Group Type” on page 8-56.

3 Declare the methods that the APTRA Author uses to


edit your Work Groups which are referred to as the
Work Group Interface. See section “Declaring the
Work Group Interface” on page 8-58.

4 Implement the Work Group Interface methods.

The implementation of these methods is dependent


on whether your Worker Class can have only one, or
more than one Work Group of a particular type.

APTRA Advance ADE, Programmer’s Guide 8-51


Implementation of Worker Classes
Implementing a Work Group

If your Coordinator can only have one Work Group


of a particular type, then see section “Declaring the
Work Group Type” on page 8-56.

If your Coordinator can have more than one Work


Group of a particular type then see section “Multiple
Work Group Interface” on page 8-61.

This section describes the first step in implementing a


Creating a Getter or Getter or Putter Work Group. See “Implementing a
Putter Work Group Work Group” on page 8-51 for more information about
Type 8 the next step.
Any Work Group that you implement in Advance ADE
is either an instance or a subclass of the
mTBasicWorkGroup class template as described in the
APTRA Advance ADE, C++ Class Reference.
The class template supplies two methods, GetWorker
and GetNumWorkers, that can be called by your Worker
Class. The first method allows your Worker Class to get
a pointer to a particular Worker in the Work Group and
the second returns the number of Workers in the Work
Group.
The class template also supplies the AddWorker and
RemoveWorker methods which allow the APTRA
Author to manipulate the Work Group’s Subworkers.
The class template has a constructor method that defines
the initial size of the array of Workers which has a
default of 2. If you want to set this value then you can set
the parameter when the Work Group is being
instantiated.
To implement a Getter Work Group Type, you should
create an instance of the mTBasicWorkGroup class
template with a Getter Worker Class ID as the template
parameter.

8-52 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Work Group

To implement a Putter Work Group Type you should


create an instance of the mTBasicWorkGroup class
template with a Putter Worker Class ID as the template
parameter.
This template instance is created as a new C++ type
using the typedef keyword. This new type is used as the
Group Type Class ID; see “Group Type Class ID” on
page 7-13.
A second type, which is a pointer to the template
instance type, is also created. This is referred to as the
Work Group pointer type.
Both these types must be created before you use them in
your Worker Class code.
Any Advance ADE Worker Class (it is recommended
that you use Abstract) can be used as the parameter to
the mTBasicWorkGroup class template.
The following is an example of the type definitions
required to produce a Getter Work Group which has
mStringGetter Subworkers, a Group Type Class ID of
StringGetterWG and a Work Group pointer type called
pmStringGetterWG.

typedef mTBasicWorkGroup<mStringGetter> StringGetterWG;


typedef StringGetterWG * pmStringGetterWG;

The Worker Classes “Example 4: Switcher” and


“Example 5: String Searcher” on page 10-5 contain
examples of Getter Work Group implementations.
The next example is of the type definitions required to
produce a Putter Work Group, which has
mIntegerPutter Subworkers, a Group Type Class ID of

APTRA Advance ADE, Programmer’s Guide 8-53


Implementation of Worker Classes
Implementing a Work Group

IntegerPutterWG and a Work Group pointer type called


pmIntegerPutterWG.

typedef mTBasicWorkGroup<mIntegerPutter> IntegerPutterWG;


typedef IntegerPutterWG * pmIntegerPutterWG;

The Worker Class “Example 9: Get Date” on page 10-4


contains an example of a Putter Work Group
implementation.

This section describes the first step in implementing a


Creating a Doer Work Doer Work Group. See “Implementing a Work Group”
Group Type 8
on page 8-51 for more information about the next step.
Every Doer Work Group that you implement in Advance
ADE is an instance of the mTDoerWorkGroup class
template as described in the APTRA Advance ADE, C++
Class Reference.
This class template contains all the methods that will
allow your Coordinator Worker Class to deactivate,
activate and give events to its Subworkers.
This class template is also a subclass of the
mTBasicWorkGroup class template, and inherits all of its
methods. See “Creating a Getter or Putter Work Group
Type” on page 8-52 for more information.
The class template has a constructor method that defines
the initial size of the array of Workers which has a
default of 2. If you want to set this value then you can set
the parameter when the Work Group is being
instantiated.
To implement a Doer Work Group Type you should
create an instance of the mTDoerWorkGroup class

8-54 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Work Group

template with a Doer Worker Class ID as the template


parameter.
Any Subclass of mDoers (including Abstract) can be
used as the parameter to the mTDoerWorkGroup class
template.

Note: If you use mDoer as the template parameter then


any Doers can be contained in the Work Group.

This template instance is created as a new C++ type


using the typedef keyword. This new type is used as the
Group Type Class ID; see “Group Type Class ID” on
page 7-13.
A second type which is a pointer to the template instance
type is also created. This is referred to as the Work
Group pointer type.
Both these types must be created before you use them in
your Worker Class code.
The following is an example of the type definitions
required to produce a Doer Work Group which has;
mDoer Subworkers, a Group Type Class ID of DoerWG
and a Work Group pointer type called pmDoerWG.

typedef mTDoerWorkGroup<mDoer> DoerWG;


typedef DoerWG * pmDoerWG;

The Worker Class “Example 4: Switcher” on page 10-5


contains an example of a Doer Work Group
implementation.

APTRA Advance ADE, Programmer’s Guide 8-55


Implementation of Worker Classes
Implementing a Work Group

This section is the second step in implementing a Work


Declaring the Work Group. It contains the information required to declare
Group Type 8
and initialise both single and multiple Work Group
Types.
This section uses the Work Group pointer type which
you have defined in step 1 and is divided into two
sections, one covering the declaration of a single and the
other a Multiple.

Note: In your Worker Class code, always refer to Work


Groups using the Work Group pointer type.

Declaring and initialising the single Work Group


Type 8

The data member that is used to reference the Work


Group Type is a Work Group pointer type.
The private data member is initialised to NULL in your
Worker Class’s constructor method.
The following is the example code fragments which you
must insert in your code. This is the same for any Work
Group Type. In the example pmWorkGroup is the Work
Group pointer type.

class mExampleClass...
{
public:
.
private:
// Create the Work Group pointer type data member
pmWorkGroup WorkGroupPointer;
.
};
// This is the class constructor which initialises the WorkGroupPointer to null
mExampleClass::mExampleClass(): WorkGroupPointer(NULL)
{
}

8-56 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Work Group

The Worker Class “Example 3: Date Setter” on page 10-4


contains an example of a single Work Group
implementation.

Declaring and initialising the multiple Work


Group Type 8

The data member that is used to reference the multiple


Work Groups of the same type is an array of Work
Group pointer types.
The private array of pointers is initialised to NULL in
your Worker Class’s constructor method.
The array’s size is the maximum number of Work
Groups plus one. This makes your Worker Class code
easier to handle as you will see in step 3, “Multiple Work
Group Interface” on page 8-61.

Note: It is your responsibility to make sure that the


maximum number you use here is the same as you
define in the Author Worker Class Definition. Errors
may occur if these numbers are not the same. For further
information, see “Maximum Subworkers” on page 7-13.

The following is the example code fragments which you


must insert in your code. This is the same for any Work
Group Type. In the example pmWorkGroup is the Work
Group pointer type and the maximum number of Work
Groups is 50.

APTRA Advance ADE, Programmer’s Guide 8-57


Implementation of Worker Classes
Implementing a Work Group

//define the maximum number of Work Groups of this type


#define MAXIMUM_NUMBER_OF_WORK_GROUPS 50

class mExampleClass...
{
public:
.
private:
// Create the array of Work Group pointer type data memeber
pmWorkGroup WorkGroupPointerArray[MAXIMUM_NUMBER_OF_WORK_GROUPS+1];
.
};
// This is the class constructor which initialises the WorkGroupPointerArray to null
mExampleClass::mExampleClass()
{
// null array of pointers to work groups
for(int i=0;i<=MAXIMUM_NUMBER_OF_WORK_GROUPS;i++)
{
WorkGroupPointerArray[i] = NULL;
}
}

The Worker Class “Example 4: Switcher” on page 10-5


contains an example of a multiple Work Group
implementation.

This section is the third step in implementing a Work


Declaring the Work Group. It describes the interface between the APTRA
Group Interface 8
Author and your Coordinator that allows the editing of
Work Groups.
To allow a user of the APTRA Author to add and remove
Work Groups from your Coordinator Worker Class,
there must be corresponding public member methods
defined in your C++ Worker Class.
These methods for adding and removing Work Groups
have the following public declaration in your Worker
Class:

8-58 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Work Group

mWorkGroup * Add_X_WorkGroup( unsigned short WGId );


void Remove_X_WorkGroup( unsigned short WGId );

In this declaration the ‘X’ value is the Group Type ID


which is used in the Author Worker Class Definition. See
“Group Type ID” on page 7-11 for more information.
The methods parameter WGid is a value greater or equal
to 1 which is the Work Group ID. This is a unique value
for Work Groups of a particular type for your
Coordinator.
Thus an example declaration of these public methods
where the Group Type ID is Format would be as follows:

class mExampleClass...
{
public:
.
mWorkGroup * Add_Format_WorkGroup(unsigned short WGId);
void Remove_Format_WorkGroup(unsigned short WGId);

private:
.
};

This section describes the fourth step in implementing a


Single Work Group Work Group. It describes the implementation of the
Interface 8
Work Group Interface methods when your Coordinator
only has to handle one Work Group of a particular type.
The methods implemented are the same as described in
the section “Declaring the Work Group Interface” on
page 8-58. Since only one Work Group is being handled,
the WGid parameter is ignored by both of the methods.
Your Add_X_WorkGroup method must create a Work
Group of the type you defined as the Group Type Class

APTRA Advance ADE, Programmer’s Guide 8-59


Implementation of Worker Classes
Implementing a Work Group

ID in step 1. It must also assign its address to the Work


Group pointer type data member defined in step 2.
The Remove_X_WorkGroup method deletes the Work
Group that was created by the Add_X_Workgroup.
The following is the Author entry for a Work Group.

This example has Doer Subworkers, a Group Type ID of


Format and a Group Type Class ID of
WorkGroupClassID.
The code required to implement the Work Group
Interface methods for this example is as follows, where

8-60 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Work Group

the Work Group pointer type data member is


WorkGroupPointer.
// This is code for the Add Work Group method.
mWorkGroup * mExampleClass::Add_Format_WorkGroup(unsigned short)
{
// Note that the parameter is never needed since there can be only one
// Work Group.
WorkGroupPointer = new WorkGroupClassID();

// Return the address of the new Work Group.


return WorkGroupPointer;
}
// This is code for the Remove Work Group method.
void mExampleClass::Remove_Format_WorkGroup (unsigned short)
{
// Note that the parameter is never needed since there can be only one
// Work Group.

// Delete the Work Group


delete WorkGroupPointer;

// reset the pointer so it is not pointing to an existing Work Group


WorkGroupPointer = NULL;
}

The Worker Class “Example 3: Date Setter” on page 10-4


contains an example of a single Work Group
implementation.

This section describes the fourth step in implementing a


Multiple Work Group Work Group. It describes the implementation of the
Interface 8
Work Group Interface methods when your Coordinator
only has to handle more than one Work Group of a
particular type.
The methods implemented are the same as described in
the section “Declaring the Work Group Interface” on
page 8-58.
Your Add_X_WorkGroup method must create a Work
Group of the type you defined as the Group Type Class

APTRA Advance ADE, Programmer’s Guide 8-61


Implementation of Worker Classes
Implementing a Work Group

ID in step 1 and store its associated Work Group


Identifier which is supplied by the APTRA Author.
The Remove_X_WorkGroup method deletes the Work
Group that was created by the Add_X_Workgroup with
the given Work Group ID.
The Author handles Work Groups as a stack with the
Work Group ID as the stack counter.
When the Author pushes a Work Group onto the stack
by calling Add_X_WorkGroup, the Work Group ID is
incremented from its initial value of 1.
When the Author pops a Work Group off the stack the
Work Group ID is decremented.
A simple way of storing a stack of Work Group pointer
types is an array, which is the method used in Advance
ADE. As you can see from the array declaration in
“Declaring the Work Group Interface” on page 8-58, the
array is declared with an extra cell. This allows the Work
Group ID to be used as the array index with no
processing of the value thus simplifying the
implementation.
Provided you have the correct maximum number of
Work Groups, there is no requirement to check the Work
Group ID against the limit, since the Author does this for
you.
The following is an example of the code required to
implement the Work Group Interface methods. In the
example the Group Type ID is Format, the Group Type
Class ID is WorkGroupClassID and the array of Work
Group pointer types is WorkGroupPointerArray.

8-62 APTRA Advance ADE, Programmer’s Guide


Implementation of Worker Classes
Implementing a Work Group

// This is code for the Add Work Group method.


mWorkGroup * mExampleClass::Add_Format_WorkGroup(unsigned short aWorkGroupId)
{
// creare new Work Group
WorkGroupPointerArray[aWorkGroupID] = new WorkGroupClassID();

// Return the address of the new Work Group.


return WorkGroupPointerArray[aWorkGroupID];
}
// This is code for the Remove Work Group method.
void mExampleClass::Remove_Doers_WorkGroup (unsigned short aWorkGroupId)
{
// Delete the Work Group
delete WorkGroupPointerArray[aWorkGroupID];

// reset the pointer so it is not pointing to an existing Work Group


WorkGroupPointerArray[aWorkGroupID] = NULL;
}

The Worker Class “Example 4: Switcher” on page 10-5


contains an example of a single Work Group
implementation.

APTRA Advance ADE, Programmer’s Guide 8-63


Implementation of Worker Classes
Implementing a Work Group

8-64 APTRA Advance ADE, Programmer’s Guide


Table of Contents
Building and Testing Guidelines

Chapter 9
Building and Testing
Guidelines

Overview 9-1

Directory Structure 9-2

Building a Worker Class 9-3


Automating the Build Process 9-3
Building a Subclass of a Worker Class 9-4

Adding a Worker Class to the Advance ADE


Runtime 9-5
Removing a Worker Class 9-8

Testing a Worker Class 9-9

Debugging a Worker Class 9-12

Troubleshooting 9-13
Problems When Running the Test Application 9-13
Possible Problem Sources 9-13

APTRA Advance ADE, Programmer’s Guide


Table of Contents
Building and Testing Guidelines

APTRA Advance ADE, Programmer’s Guide


Building and Testing Guidelines
9

Overview

Overview 9

This chapter provides information on how to build and


test user-created Advance ADE Worker Classes.

APTRA Advance ADE, Programmer’s Guide 9 -1


Building and Testing Guidelines
Directory Structure

Directory Structure 9

The Worker Class directory structure is shown in Figure


9-1.

Figure 9-1
Worker Class Directory Structure
9

9-2 APTRA Advance ADE, Programmer’s Guide


Building and Testing Guidelines
Building a Worker Class

Building a Worker Class 9

This section describes the requirements for building your


Worker Class.
In order to help you with the Build Process, a Project is
supplied with Advance ADE which you can use to
automate most of the process.
If you are building a Worker Class which is a subclass of
another Worker Class, see “Building a Subclass of a
Worker Class” on page 9-4.

This section explains how you can automate most of the


Automating the Build Build Process using the Project files for one of the
Process 9
example Worker Classes supplied with Advance ADE.
This Project files are wcexam1.dsw and wcexam1.dsp,
located in the
<GLOBAL>\FINAL\ULYSSES\SUPPORT\USER\WC
EXAM1 directory.

Customising the Project 9

In order to customise these files, copy them to your own


working directory and rename them to reflect your
Worker Class’s file name.
You then have to use the Visual C++™ IDE to edit the
files as stated in the header. This includes changing the
wcexam1.dsw and wcexam1.dsp filenames to your own
Worker Class’s filename.
The Project is designed to be run from the directory that
contains your Worker Class source and header.

APTRA Advance ADE, Programmer’s Guide 9-3


Building and Testing Guidelines
Building a Worker Class

Using the Project 9

Once the wcexam1.dsw and wcexam1.dsp files have been


modified, they can be used to provide an automated
Build Process. Use the Visual C++™ IDE to
1 Compile the Worker Class source to an object in the
directory.

2 Link the object to produce a DLL in a RELEASE


subdirectory of the Worker Class’s directory.

3 Create an import library in the


<GLOBAL>\FINAL\ULYSSES\LIB directory.

4 Copy the Worker Class header to the


<GLOBAL>\FINAL\ULYSSES\INCLUDE
directory.

If you are building a Worker Class that is a subclass of


Building a Subclass of another Worker Class you have produced then you have
a Worker Class 9
a few things you must take into account (based on the
classes being in separate modules).
● The subclass must be able to link with the import
library (lib) produced for the base Worker Class.
● The subclass is dependent on the base class Worker
Class and thus its lib should be part of the
dependencies in the subclass’s .dsw and .dsp files.
For an example of this see the Worker Class example
“Example 11: Convert To Upper” on page 10-6.

9-4 APTRA Advance ADE, Programmer’s Guide


Building and Testing Guidelines
Adding a Worker Class to the Advance ADE Runtime

Adding a Worker Class to the


Advance ADE Runtime 9

This section describes the files required and the process


by which your Worker Class is added to the Advance
ADE Runtime.
If you want to remove a Worker Class, read the next
section “Removing a Worker Class”.
The following is a list of the required files that have been
built from your Worker Class source (see “Building a
Worker Class” on page 9-3) and where they must be
located:
● DLL
● LIB
● Header (.h) file.
For information on your Worker Class header file, see
“Implementing a Worker Class” on page 7-23.
The directory structure and file locations are shown in
Figure 9-2.

APTRA Advance ADE, Programmer’s Guide 9-5


Building and Testing Guidelines
Adding a Worker Class to the Advance ADE Runtime

Figure 9-2
Worker Class Runtime File
9

Locations
DLL files
.h files
LIB files

DLL files
.h files
LIB files

When you have placed all the files in the correct


directories, you can then add your Worker Class to the
Advance ADE Runtime.

9-6 APTRA Advance ADE, Programmer’s Guide


Building and Testing Guidelines
Adding a Worker Class to the Advance ADE Runtime

This is done by creating a new Worker Class in the


Author as follows:
1 Select the Catalog you wish your new Worker Class
to be in.

2 Select on the Author Menu


Component->New->Worker class

3 Select from the list the Metaclass of your Worker


Class.

4 The Worker Class Notebook will now appear. Enter


the information you defined in your Worker Class’s
Author Worker Class Definition.

5 Select OK when you have finished entering all the


information.

6 Then you must invoke Build Factory in the Author Tools


menu which will then allow you to run instances of
your Worker Class.
Once you have built the Worker Factory you only have
to rebuild it if you change the interface to your new
Worker Class.
If you get an error when you build your Worker Factory
see Appendix C, “Build Errors”.
Your Worker Class is now available to be tested.
If you are adding more than one Worker Class to the
Advance ADE Runtime, add them one at a time, and
then do a Worker Factory Build. This makes diagnosing
any problems much easier.

APTRA Advance ADE, Programmer’s Guide 9-7


Building and Testing Guidelines
Adding a Worker Class to the Advance ADE Runtime

Only after you have built a Worker Factory, and tested


the new Worker Class should you consider doing a Final
Application Build.
When you build a Final Application (see the APTRA
Advance ADE, User’s Guide) or a Worker Factory,
Advance ADE uses the Visual C++™ Release 6.0
Compiler to perform the build. For information on the
errors that can occur see Appendix C, “Build Errors”.

Note: Building your Worker Class and building an


Application are separate tasks. Even though your code
generated no errors when the Worker Class DLL was
created, you can still generate errors when it is combined
with the Advance ADE Runtime.

In order to minimise the possibility of conflicts, and


Removing a Worker minimise the size of your Final Applications, it is a good
Class 9
idea to remove any Worker Class examples you do not
require.
To remove the Worker Class from the Runtime, perform
the following steps:
1 Delete the Worker Class and any Worker instances of
it from the APTRA Author by selecting Remove from
the Author Edit menu or its pop-up menu.

2 Remove the Worker Class DLL.

3 Remove the Worker Class LIB.

4 Remove the Worker Class header file.

5 Rebuild the Worker Factory by invoking Build


Factory from the Author Tools menu.

9-8 APTRA Advance ADE, Programmer’s Guide


Building and Testing Guidelines
Testing a Worker Class

Testing a Worker Class 9

This section contains a description of the testing of your


Worker Class. It is imperative that a Worker Class is
rigorously tested before being used in an Advance ADE
application.
You can only use the Author to test your Worker Class,
since you are not supplied with a Worker Class test
harness. However, you could write your own.

The recommended methodology for testing your new


Worker Class is a multistage process as follows:

1 The first stage of testing is done by creating a small


test Application, with only a few Workers, in the
APTRA Author.

This is first used to test that the Worker Class


interface is correct.

To test that these are correct, some test code can be


added to your Worker Class. The following code
example shows how to test a Doer interface.

The test output from this code can be found in the


\<GLOBAL>\debug.out file.

APTRA Advance ADE, Programmer’s Guide 9-9


Building and Testing Guidelines
Testing a Worker Class

:
// Must include fstream.h for the test statements but should be removed after testing
#include <fstream.h>
// create the DebugOut stream
ofstream DebugOut;
// constructor
mSimpleDoer::mSimpleDoer()
{
// open the stream, and output that the class has been instantiated
DebugOut.open ("\\GLOBAL\\DEBUG.OUT");
DebugOut.setf(ios::unitbuf);
DebugOut << "Simple Doer instantiated \n";
}
// destructor
mDoerDoer::~mSimpleDoer()
{
DebugOut << "deleted \n";
DebugOut.close();
}
// start method
void mSimpleDoer::Start(mEventContext * aEC, mWorkContext &, mWorkContext * )
{
// write out that the start procedure is being executed
DebugOut << "Start \n";
:
// write out any user events being posted
DebugOut << "User Event " << USER_MESSAGE << "\n";
}
// stop method
mSignal * mSimpleDoer::Stop(mEventContext * aEC, mWorkContext & aWC )
{
//write out the stop procedure is being executed
DebugOut << "Stop \n";
:
//write out the late user event found
DebugOut << "Late Event \n";
:
// write out the late signal
DebugOut << "Late Signal " << "SUCCESS" << "\n";
:
}

9-10 APTRA Advance ADE, Programmer’s Guide


Building and Testing Guidelines
Testing a Worker Class

// ProcessEvent method
mSignal* mSimpleDoer::ProcessEvent(mEventContext* aEC, mWorkContext& aWC,
const mEvent* aEvent)
{
// output that process event is being executed
DebugOut << "Process Event\n";
:
// output any signals that have occurred
DebugOut << "Signal " << "SUCCESS" << "\n";
:
}

Once the code has been added and the Worker Class
built, it is tested by executing the test Application.
The execution of the test Application is then
compared against what has been written to the
debug.out file.

Code similar to that which has been shown can be


used to test any Attribute or Work Group defined in
the Worker Class.

Putters and Getters can also be tested using similar


code.

2 The final test is done to check that the Worker Class


as a whole performs correctly when called from the
small test Application.
Only after the extensive testing has been completed
should the new Worker Class be made available for use
by your Advance ADE application.

APTRA Advance ADE, Programmer’s Guide 9-11


Building and Testing Guidelines
Debugging a Worker Class

Debugging a Worker Class 9

If you are getting problems when executing your Worker


Class, perform the following steps:
1 Make sure that you have carried out the
recommended test procedure (described in “Testing
a Worker Class” on page 9-9).

2 Check “Troubleshooting” on page 9-13 to see if any


information there helps you with your problem.

3 See Appendix B, “Debugging Your Advance ADE


Application with Visual C++™”.

9-12 APTRA Advance ADE, Programmer’s Guide


Building and Testing Guidelines
Troubleshooting

Troubleshooting 9

This section provides information about possible


problems that may occur with your new Worker Classes.
If you are having problems clearing faults, read the
APTRA Self-Service Support, System Application User Guide
which provides guidance on dealing with them.

This is a list of problems that may occur when running


Problems When your test Application in the Author.
Running the Test
Application 9
Your Worker Class DLL cannot be found 9

This error occurs because you have not put the Worker
Class DLL in the <GLOBAL>\TEST\DLL directory.

Your Worker Class Help cannot be found 9

This error occurs because either:


● You have not put the Worker Class Help in the
<GLOBAL>\HELP directory
● You have used the incorrect Component ID.

When entering the Worker Class Definition into the


Possible Problem Author, it is not checked against the actual Worker Class
Sources 9
source. It is therefore a likely source of problems.
Only some errors will be flagged when you do a Worker
Factory or Final Application build.
Some errors will appear when you actually execute the
Worker Class.
Others will simply cause spurious errors.

APTRA Advance ADE, Programmer’s Guide 9-13


Building and Testing Guidelines
Troubleshooting

If you are having difficulties finding the source of a


problem, see the following list of possible causes, which
would not necessarily be picked up by a Worker Factory
build:
● Attributes

If you have entered an incorrect Attribute ID it will


be picked up in a Worker Factory build.

If you have entered an incorrect Attribute Type it


may cause the Worker Factory build to fail.

Since the default value has no check on it, the default


defined in the Worker Class can be completely
different to the default defined in the Author.

● Message Types

No checking is done that you have selected the


correct message types when you have entered the
Worker Class Definition.

When you use a Worker Class, you may find it listed


as being able to go into Work Groups you never
intended to use it in, and/or it cannot go into the
intended Work Groups.

● Metaclass

If you have created an Abstract, but enter this into


the Author as a Loner, it will cause an error in a
Worker Factory build.

If you have entered a Loner as an Abstract or


Sequencer, or a Sequencer as a Loner or Abstract, no
build errors will occur.

9-14 APTRA Advance ADE, Programmer’s Guide


Building and Testing Guidelines
Troubleshooting

When you try and use your Worker Class, but it has
been entered incorrectly, you will find you cannot
use it as intended.

To change the Metaclass to the correct one you must


re-enter the entire Worker Class Definition.

● Signals

If you have entered an incorrect Signal ID it will not


cause an error in a Worker Factory build.

Possible outcomes of the incorrect Signal ID when


your Application is executing are:

● The Signal reaches the Top Worker and is flagged


as an unconsumed Signal.
● The Signal causes an incorrect path to be taken in
your Application.
● Superclass

If you have created a Worker Class that is not a Doer,


but you make it a Doer in the Author, it will not give
a Worker Factory build error. However, if you put it
in a Doer Work Group, it will give an error in a Final
Build, and it will cause a runtime error when
executed.

If you have created a Worker Class that is not a


Getter/Putter, but make it a Getter/Putter in the
Author, it will not give a Worker Factory build error.
However, if you put it in a Getter/Putter Work
Group, it will give an error in a Final Build, but it will
not give an error when executed.

In the Author, if you forget to select a Superclass for


a Worker Class to inherit from, you will not be able
to put the Worker into a Work Group requiring that
inheritance.

APTRA Advance ADE, Programmer’s Guide 9-15


Building and Testing Guidelines
Troubleshooting

If you select an extra Superclass for your Worker


Class that it does inherit from, you will be able to put
the class in Work Groups for which it is not intended.
This can cause problems.

● Work Groups

If you have entered an incorrect Group Type ID,


Subworker Class or Group Type Class ID, it will
cause an error in a Worker Factory build.

There is no check on the Maximum Number of Work


Groups value.

There is no check on the Maximum and Minimum


Number of Subworkers.

If the number of Work Groups or Subworkers is


more than your Worker Class can handle, problems
may occur.

If the Signal Consumer is wrong, it can cause the


Author to ignore all the Signals generated by
Subworkers.

If you choose the incorrect message type, this could


allow the wrong type of Subworker to be allowed in
the Work Group.

9-16 APTRA Advance ADE, Programmer’s Guide


Table of Contents
Advance ADE Worker Class Examples

Chapter 10
Advance ADE Worker Class
Examples

Overview 10-1

Introduction 10-2
File Names 10-2
File Locations 10-2
Adding Examples to the Advance ADE Runtime 10-3

Example Classes 10-4


Example 1: Trace 10-4
Example 2: System Time 10-4
Example 7: Simple Signaller 10-4
Example 3: Date Setter 10-4
Example 9: Get Date 10-4
Example 4: Switcher 10-5
Example 5: String Searcher 10-5
Example 6: Eject Card 10-5
Example 8: Convert Handle TM 10-6
Example 10: Base String 10-6
Example 11: Convert To Upper 10-6

APTRA Advance ADE, Programmer’s Guide


Table of Contents
Advance ADE Worker Class Examples

APTRA Advance ADE, Programmer’s Guide


Advance ADE Worker Class Examples
10

Overview

Overview 10

This chapter describes the Worker Class examples that


are supplied with Advance ADE and how they can be
added to the Advance ADE Runtime.
The example classes are as follows:
Example 1: Trace
Example 2: System Time
Example 3: Date Setter
Example 4: Switcher
Example 5: String Searcher
Example 6: Eject Card
Example 7: Simple Signaller
Example 8: Convert Handle TM
Example 9: Get Date
Example 10: Base String
Example 11: Convert To Upper.

APTRA Advance ADE, Programmer’s Guide 10 -1


Advance ADE Worker Class Examples
Introduction

Introduction 10

The names of the files associated with the Worker Class


File Names 10

examples are in the form wcexamn, with the appropriate


extension, where n is the example number.
The files associated with each example are described in
the table below.

Table 10-1 File Type Extension Description


Example File Types
Source .cpp C++ source code

Header .h C++ header: has the same name as


the source file

Project .dsp, Files that build the Worker Class


file .dsw DLL: have the same name as the
source file

All the output files generated from these example files


will have the same name as the source file.

The directory structure and file locations are shown in


File Locations 10

the following figure.

10-2 APTRA Advance ADE, Programmer’s Guide


Advance ADE Worker Class Examples
Introduction

Figure 10-1
Worker class Runtime File
10

Locations

wcexam1.cpp
wcexam1.h
wcexam1.mak

The example classes can be added to the Advance ADE


Adding Examples to Runtime by following the procedures described in
the Advance ADE Chapter 9, “Building and Testing Guidelines”.
Runtime 10

APTRA Advance ADE, Programmer’s Guide 10-3


Advance ADE Worker Class Examples
Example Classes

Example Classes 10

The Worker Class examples supplied with Advance


ADE are described below in order of complexity.

This is a Simple Doer with a single Attribute. It writes


Example 1: Trace 10

the Attribute to a file which can be used for tracing the


activation of an Application.
Files: wcexam1.h, wcexam1.cpp, wcexam1.mak

Source code file: wcexam2.cpp


Example 2: System
Time 10
This is a String Giver (Getter) and Receiver (Putter). It
returns the system time or sets the time.

Source code file: wcexam7.cpp


Example 7: Simple
Signaller 10
This is a Simple Signaller Doer. It sends a User Event to
itself and generates a Signal.

Source code file: wcexam3.cpp


Example 3: Date Setter 10

This is a Simple Doer which is a Getter Coordinator with


one Getter Work Group. It gets the date from the Worker
in the Getter Work Group and uses it to set the system
date.

Source code file: wcexam9.cpp


Example 9: Get Date 10

This is a Simple Doer which is a Putter Coordinator with


one Putter Work Group. It reads the system date and
gives it to the Worker in the Putter Work Group.

10-4 APTRA Advance ADE, Programmer’s Guide


Advance ADE Worker Class Examples
Example Classes

Source code file: wcexam4.cpp


Example 4: Switcher 10

This is a Doer Coordinator with a series of Doer Work


Groups and is also a Getter Coordinator with one Getter
Work Group. It gets the index value from the Worker in
the Getter Work Group and executes one of the Doer
Work Groups.

Source code file: wcexam5.cpp


Example 5: String
Searcher 10
This is a Multi-Thread Signaller Doer which is a Getter
Coordinator. It has a Getter Work Group which can have
up to 50 Workers, and a data Attribute called 'Compare
String'.
When this Worker is started it initiates a subthread. The
subthread compares the string in the Worker’s 'Compare
String' Attribute with the strings returned by the
Workers in the Work Group. If a match is found, a
'Successful' signal is generated, otherwise a 'Failed'
signal is generated. The Worker achieves this by posting
a User Event to itself from the subthread, which will be
processed by its ProcessEvent method.
This Worker also demonstrates how to process late
events when the Worker is being stopped.

Source code file: wcexam6.cpp


Example 6: Eject Card 10

This is an example Event Signaller Doer which uses


ADI-2 calls. It sets up a second thread which sends an
eject card command to the card reader device. This
Worker generates a Signal based on whether the card
eject succeeds or not.
This Worker handles both solicited and unsolicited
Events and uses the new ADI-2 function
ADI_M_SETUP_MONITOR.

APTRA Advance ADE, Programmer’s Guide 10-5


Advance ADE Worker Class Examples
Example Classes

Source code file: wcexam8.cpp


Example 8: Convert
Handle TM 10
This is a Handle Receiver (Putter) and a Putter
Coordinator with two Putter Work Groups.
When given a Handle containing the data structure tm as
set up by the external function GetLocalTime (see
“Example 5: Using External Data” on page 5-24), this
worker converts it into a date and time string. These
strings are then given to the appropriate Workers.
The C Function in Example 5 must be registered.

Source code file: wcexam10.cpp


Example 10: Base
String 10
This is an Abstract String Receiver (Putter). It is the base
class for a group of Worker Classes that manipulate
mStrings.
When given an mString, this worker stores it in an
Attribute called ‘Base Text’ for manipulation by a
subclass.

Source code file: wcexam11.cpp


Example 11: Convert
To Upper 10
This is a Loner String Giver (Getter) which is a subclass
of the Base String Worker Class above. It inherits the
Base Text Attribute and the String Receiver functionality
from Base String.
When sent a Get String message, this worker will return
a stored string converted to Upper Case.
Example 10: Base String must be built before this
example as this class is dependent on the wcexam10.lib
import library.

10-6 APTRA Advance ADE, Programmer’s Guide


Appendices

Appendix A ADI-2 Interfacing

Appendix B Debugging Your Advance ADE Application with


Visual C++™

Appendix C Build Errors

Appendix D Modifying Advance ADE Runtime

Appendix E Related Documentation

APTRA Advance ADE, Programmer’s Guide


APTRA Advance ADE, Programmer’s Guide
Table of Contents
ADI-2 Interfacing

Appendix A
ADI-2 Interfacing

Overview A-1

Introduction A-2

ADI-2 Interfacing Guidelines A-3

ADI-2 Interfacing Example A-5

APTRA Advance ADE, Programmer’s Guide


Table of Contents
ADI-2 Interfacing

APTRA Advance ADE, Programmer’s Guide


ADI-2 Interfacing
A

Overview

Overview A

This Appendix describes how to use ADI-2 from an


Advance ADE Application.
The Introduction discusses reasons for interfacing
directly between an Advance ADE Application and
ADI-2.
The ADI-2 Interfacing Guidelines give information on
how to interface between an Advance ADE Application
and ADI-2.
The ADI-2 Interfacing Example section presents a
working example of an interface between an Advance
ADE Application and ADI-2.

APTRA Advance ADE, Programmer’s Guide A -1


ADI-2 Interfacing
Introduction

Introduction A

Reasons for interfacing your Advance ADE Application


directly with ADI-2 are as follows:
● You wish to port existing code into your Advance
ADE Application.
● You wish to access low level functions that cannot be
accessed with the Worker Classes supplied with
Advance ADE.
You should note that while use of direct ADI-2 calls is
possible, it is recommended that you use the Advance
ADE Worker Classes.

A-2 APTRA Advance ADE, Programmer’s Guide


ADI-2 Interfacing
ADI-2 Interfacing Guidelines

ADI-2 Interfacing Guidelines A

This section contains guidelines for direct interfacing


between an Advance ADE Application and ADI-2.
To allow ADI-2 functions to be called from an Advance
ADE Worker Class or an external C function resident in a
DLL, these guidelines must be followed. The ADI-2
references can be found in the APTRA Self-Service
Support, Programmer’s Reference.
● An extension to ADI-2 called
ADI_M_SETUP_MONITOR has been introduced.
This extension should be used instead of
ADI_SETUP_MONITOR since it allows the
monitoring of both services and channels for
solicited and unsolicited events.

See the APTRA Advance ADE, C++ Class Reference


publication for more information about this
extension.

● You can make non-blocking Self-Service Support


calls from the main thread of an Advance ADE
Application without needing to register with
Self-Service Support. This is because the Advance
ADE Application registers with Self-Service Support
in its initialisation code.
● If you want to make a blocking call such as
ADI_RECEIVE_EVENT you must first create your
own thread. This prevents your call holding up
events that the calling thread may be looking for.

APTRA Advance ADE, Programmer’s Guide A-3


ADI-2 Interfacing
ADI-2 Interfacing Guidelines

● If you want to make ADI-2 calls in your own thread


you must first call ADI_INITIALISE to register the
thread with Self-Service Support Before terminating
your thread you should call ADI_TERMINATE.
● If you want to receive events on your thread from a
Self-Service Support service you must call
ADI_M_SETUP_MONITOR before
ADI_RECEIVE_EVENT. When you no longer
require events you should call
ADI_REMOVE_MONITOR.
● You should use the Advance ADE Resource
Management Worker Classes to manage resources
and not the ADI-2 functions ADI_ATTACH and
ADI_DETACH.

The Advance ADE Worker Classes manage the


resources at the Application level. This means that
when exclusive access to a service is obtained, it is
done on behalf of the complete Application process.
Thus the service can be accessed from any thread in
your Advance ADE Application. An ADI-2 Attach
call enables safe access only in the thread that made
the call.

● You can use NVRAM interface calls but you will find
that the Advance ADE persistent stores are much
easier to use for any new code you develop.
● You may find that errors occur when you build the
source that uses the ADI-2 function calls. If these are
problems due to parameter types, try explicitly
typing the parameters.

For example:
ADI_LOOKUP_NAME((unsigned char*) "MCRW", &mcrw_sadd);

A-4 APTRA Advance ADE, Programmer’s Guide


ADI-2 Interfacing
ADI-2 Interfacing Example

ADI-2 Interfacing Example A

This example illustrates the use of ADI-2 calls in an


Advance ADE Application to access a Self-Service
Support service in a private thread.

#define SEND_LENGTH 1
#define SEND_DATA 1
// define the structure for use in the ADI_SEND
struct WRITEDATA{
unsigned int LENGTH;
unsigned char DATA[SEND_LENGTH];
};
// define the command
struct WRITEDATA COMMAND = { SEND_LENGTH, SEND_DATA };

// Sample of code to access service from private thread


// initialise the thread
ADI_INITIALISE();
// get the service address
ADI_LOOKUP_NAME((unsigned char*)"MCRW",MCRWPTR);
// monitor for events using the new extension to ADI-2
ADI_M_SETUP_MONITOR(MCRWPTR);
// send command
ADI_SEND(MCRWPTR, WRITE, &COMMAND);
// receive response
ADI_RECEIVE(MCRWPTR, ...);
// wait for event
ADI_RECEIVE_EVENT(ListIncludingMCRW, ...);
//
// Your own code should be here to process the particular event.
//
// stop monitoring
ADI_REMOVE_MONITOR(MCRWPTR);
// finally terminate Self-Service Support access
ADI_TERMINATE();

For another example of the use of ADI-2 calls, see


“Example 6: Eject Card” on page 10-5.

APTRA Advance ADE, Programmer’s Guide A-5


ADI-2 Interfacing
ADI-2 Interfacing Example

A-6 APTRA Advance ADE, Programmer’s Guide


Table of Contents
Debugging Your Advance ADE Application with Visual C++™

Appendix B
Debugging Your Advance
ADE Application with Visual
C++™

Overview B-1

Introduction B-2

Debugging on the Development PC B-3

Debugging on an SST B-6

Debugging on a Remote PC or SST B-7

Locating Errors Using MAP files B-10

APTRA Advance ADE, Programmer’s Guide


Table of Contents
Debugging Your Advance ADE Application with Visual C++™

APTRA Advance ADE, Programmer’s Guide


Debugging Your Advance ADE Application with Visual C++™
B

Overview

Overview B

This Appendix describes how to debug an Advance ADE


Application which includes user-created Worker
Classes, using the Visual C++™ Release 5.0 debugging
tools.

APTRA Advance ADE, Programmer’s Guide B -1


Debugging Your Advance ADE Application with Visual C++™
Introduction

Introduction B

Debugging of Advance ADE Applications can be carried


out at different stages of development, and in various
environments. The following sections deal with:
● Debugging on the Development PC - describes the
procedure for debugging test and final applications
in the development environment
● Debugging on an SST - gives additional information
on debugging final applications on a local SST
● Debugging on a Remote PC or SST - gives
information on debugging final applications on
remote devices.
● Locating Errors Using MAP files - contains further
information on locating errors without the aid of
debugging facilities.

B-2 APTRA Advance ADE, Programmer’s Guide


Debugging Your Advance ADE Application with Visual C++™
Debugging on the Development PC

Debugging on the
Development PC B

The procedure for debugging an Advance ADE


Application is as follows:
1 In the Author, perform a ‘Build Final’ on the user
application containing the worker classes to be
tested, if this has not already been done.

2 Create another Advance ADE application (hereafter


referred to as SSDS_APP_DLL). It must contain an
SSDS DLL Interface worker which references the
application DLL built in step 1.

3 Open the Author project file containing the


SSDS_APP_DLL application, if it is not already open.

4 Note the component ID for the SSDS_APP_DLL


Application component.

5 In Visual C++™, load the project file containing the


source code for the worker classes to be tested.
Ensure that the source DLL has been built with full
debugging information.

6 Set break points in the source code.

7 Specify the Visual C++™ project settings as


described in “Project Settings” on page B-4.

8 Start debugging and debug as for any application.

APTRA Advance ADE, Programmer’s Guide B-3


Debugging Your Advance ADE Application with Visual C++™
Debugging on the Development PC

More detailed information is provided in the following


subsections.

When the DLL containing the user-created functions or


Build Final User classes has been built and incorporated into the APTRA
Application B
Author, the ‘Build Final’ process is performed on the
user application as described in the APTRA Advance
ADE, User’s Guide.

The project settings should be as shown in Figure B-1,


Project Settings B

with <GLOBAL>\test\support\system\apptest.exe as
the executable for debug and the SSDS_APP_DLL
Application component ID as the Program argument.

Additional DLLs B

If you want to debug worker classes in more than one


DLL, the additional DLLs must be specified.
To do this, select the Additional DLLs item in the
Category drop down list and add the name only,
without the path, of the DLL.
For example, an additional DLL called MyWorker.dll
would be entered as shown in Figure B-2.

For information on debugging in Visual C++™, refer to


Test & Debug the Visual C++™ On-line Help and documentation.
Application B

B-4 APTRA Advance ADE, Programmer’s Guide


Debugging Your Advance ADE Application with Visual C++™
Debugging on the Development PC

Figure B-1
Local debugging —
B

Project Settings

Figure B-2
Local debugging —
B

Additional DLLs

APTRA Advance ADE, Programmer’s Guide B-5


Debugging Your Advance ADE Application with Visual C++™
Debugging on an SST

Debugging on an SST B

In order to carry out debugging on a local SST, the


following software must be loaded on the SST:
● Visual C++™
● the user-developed applications, created by
performing a ‘Build Final’ in the Author
● the source code for the worker classes to be
debugged.
The procedure for debugging an Advance ADE
Application is as follows:
1 In Visual C++™, load the project file containing the
source code for the worker classes to be tested.
Ensure that the source DLL has been built with full
debugging information.

2 Specify the user application executable as the target


executable for debugging. For information on
specifying project settings, see “Project Settings” on
page B-4.

3 Set break points in the source code.

4 Specify any additional DLLs required. For more


information, see “Additional DLLs” on page B-4.

5 Debug as for any application.

B-6 APTRA Advance ADE, Programmer’s Guide


Debugging Your Advance ADE Application with Visual C++™
Debugging on a Remote PC or SST

Debugging on a Remote PC or
SST B

The information given below applies to debugging from


a local PC or SST to a remote PC or SST.
It is advisable to be proficient in debugging on local
devices before attempting remote debugging.
The pre-requisites for remote debugging are as follows:
● The local and remote devices must be connected via a
Windows NT or Windows XP TCP/IP network link
● The IP address of the remote device must be known
● The same level of Advance ADE and user-developed
software must exist on both devices.
In order to carry out debugging on a remote PC or SST,
the following software must be loaded on the local
PC/SST and remote PC/SST:

Local PC/SST Remote PC/SST

Visual C++™ Remote Debug Monitor

Debug versions of the DLLs Debug versions of the DLLs


containing the worker containing the worker
classes to be debugged classes to be debugged

Source code for the worker Built user applications


classes (created by performing a
‘Build Final’ in the Author)

APTRA Advance ADE, Programmer’s Guide B-7


Debugging Your Advance ADE Application with Visual C++™
Debugging on a Remote PC or SST

The procedure for remote debugging is described in


detail in the Visual C++™ on-line help. You should read
this first and then follow the procedure given below:
1 In Visual C++™, load the project file containing the
source code for the worker classes to be tested.
Ensure that the source DLL has been built with full
debugging information.

2 In the Project Settings, specify the path and file name


of the executable on the remote device as the user
application executable, as shown in Figure B-3.

3 Set break points in the source code.

4 Specify any additional DLLs required as shown in


Figure B-4.

5 Debug as for any remote application.

B-8 APTRA Advance ADE, Programmer’s Guide


Debugging Your Advance ADE Application with Visual C++™
Debugging on a Remote PC or SST

Figure B-3
Remote debugging
B

— Project Settings

Figure B-4
Remote debugging
B

— Additional DLLs

APTRA Advance ADE, Programmer’s Guide B-9


Debugging Your Advance ADE Application with Visual C++™
Locating Errors Using MAP files

Locating Errors Using MAP


files B

The sources of runtime errors in the SST environment


can be found even when no debug facility is available, by
the use of MAP files.
MAP files are created during the build process, and it is
therefore important that DLLs should be built with full
MAP files, and that these should be retained with the
DLLs for future reference.
Refer to the Visual C++™ on-line help for more details
on using MAP files.

B-10 APTRA Advance ADE, Programmer’s Guide


Table of Contents
Build Errors

Appendix C
Build Errors

Overview C-1
What Happens When a Build Error Occurs? C-1
Types of Errors C-1
Error Entries C-2
What To Do When You Get a Build Error C-4

Common Build Errors C-5

Final Build Errors C-7

Worker Factory Build Errors C-8

APTRA Advance ADE, Programmer’s Guide


Table of Contents
Build Errors

APTRA Advance ADE, Programmer’s Guide


Build Errors C

Overview

Overview C

This appendix details the errors that can occur when an


Advance ADE Application or Worker Factory is built.

When you build the Worker Factory or Final Application


What Happens When and an error occurs, the build is aborted and the errors
a Build Error Occurs? C
are displayed. These errors are contained in a file called
out.txt which can be found in the Windows NT or
Windows XP root directory.
The information in this file can be used to discover the
cause of the problem. Note that some of the files being
compiled are temporary files, created in the temporary
directory \<GLOBAL>\TEMP. These files are not
deleted if the build fails, and are thus available for you to
examine.

The errors are listed in alphabetic order in three groups,


Types of Errors C

dependent on Application Build type as follows:


● Common Build Errors

These errors are common to both the Final


Application and the Worker Factory Builds.

● Final Build Errors

These errors can only occur while building a Final


Application.

● Worker Factory Build Errors

These errors can only occur while building the


Worker Factory.

APTRA Advance ADE, Programmer’s Guide C-1


Build Errors
Overview

Each of the error entries in this appendix contains the


Error Entries C

error message, a list of possible causes, and the


recommended remedial action.
The error message is that displayed by the Author after
the Build has failed. These errors are also stored in the
out.txt file.
If an error message is shown without a list of possible
causes and remedial actions, then the first table found
after that message should be used.
In each error entry in the appendix variable names are
shown in italics surrounded by angle brackets (<>).
These variables will be replaced by the appropriate
names in the actual error messages.
The variables and what they represent are shown in the
following table.

Table C-1 Variables Meaning


Build Error Variables
AttributeID The Attribute ID of an Attribute as you
have defined it in the Author.

AttributeType The Attribute’s Literal Type as you have


defined it in the Author.

AuSubworker The Class ID of the Subworkers that can


be put in the Work Group as you have
defined it in the Author.

ClassInclude The name of the include file where


ClassID is defined.

ClassID This the Class ID of the Worker Class as


you have defined it in the Author.

C-2 APTRA Advance ADE, Programmer’s Guide


Build Errors
Overview

Variables Meaning

ClassConstructor The constructor method for a given


ClassID, for example:
mSimpleDoer::mSimpleDoer()

ClassDestructor The destructor method for a given


ClassID.

GTClassID The Group Type Class ID of the Work


Group as you have defined it in the
Author.

GroupTypeID The Group Type ID of the Work Group


as you have defined it in the Author.

SuperclassID The Class ID of the Superclass which


your Worker Class inherits from as you
have defined it in the Author.

SSDSTemp This is a temporary file created by the


Author during the build.

WGSubworker The Class ID of the Subworkers that can


be put in the Work Group as you have
defined it in your header.

APTRA Advance ADE, Programmer’s Guide C-3


Build Errors
Overview

When you get a build error you should look in this


What To Do When appendix to find the error message.
You Get a Build Error C

You should only look for the first error message in out.txt
since this is the one listed in this appendix. Only if a
message could be ambiguous are there other error
messages.
If you were building a Worker Factory when the error
occurred, you must search through the Worker Factory
and Common Build Errors sections to find the error
message.
Similarly, if you were building a Final Application when
the error occurred, you should search through the Final
and Common Build Errors sections to find the error
message.
Once you have found the error message you will find a
list of possible causes and recommended actions. You
should go through this list, until you have found the
cause.
Perform the recommended action, and then try the build
again.

Note: If the recommended action causes a change to the


Worker Class source code or header you should rebuild
the Worker Class dll before building the Application
again.

C-4 APTRA Advance ADE, Programmer’s Guide


Build Errors
Common Build Errors

Common Build Errors C

“Error C2039: Add_<GroupTypeID>_WorkGroup” is not a member of


“<ClassID>”

Possible Causes Recommended Action

<GroupTypeID> has not been defined Check that <ClassID> has been defined
in <ClassInclude>. properly in <ClassInclude>.

There is a mismatch between the Check that <GTClassID> is the same as


<GroupTypeID> defined in the Author the Group Type Class ID defined in
and the one defined in <ClassInclude>. <ClassInclude>.

“Error C2664: Cannot convert from “<AuSubworker>*” to


“<WGSubworker>*”. Types pointed to are unrelated. Conversion requires
reinterpret_cast, C-style cast or function-style cast”

Possible Causes Recommended Action

There is a mismatch between the Check that <AuSubworker> is the same


Subworker defined in the Author and as Work Group Subworker Type
the one defined in <ClassInclude>. defined in <ClassInclude>.

“Error LNK2001: unresolved external symbol


“<ClassID>::SetStartGroup(...)”

Possible Causes Recommended Action

Worker Class lib not found during Check that you have copied the
build. Worker Class lib to
<GLOBAL>\TEST\LIB.

APTRA Advance ADE, Programmer’s Guide C-5


Build Errors
Common Build Errors

“Error C2039: “set_<AttributeID>” is not a member of “<ClassID>””

Possible Causes Recommended Action

<AttributeID> has not been defined in Check that <AttributeID> has been
<ClassInclude>. defined in <ClassInclude>.

There is a mismatch between the Check that <AttributeID> is the same as


<AttributeID> defined in the Author the Attribute ID defined in
and the one defined in <ClassInclude>. <ClassInclude>.

“Error C2501: <ClassID>: missing decl-specifiers”

Possible Causes Recommended Action

There is a mismatch between the Check that <ClassID> is the same as the
<ClassID> defined in the Author and Worker Class ID defined in
the one defined in <ClassInclude>. <ClassInclude>.

<ClassInclude> has not been copied to Check that <ClassInclude> is in the


the <GLOBAL>\TEST\INCLUDE <GLOBAL>\TEST\INCLUDE
directory. directory.

“Error C2065: ‘<ClassID>’: Undeclared identifier”

Possible Causes Recommended Action

The Class created in the Author Make sure that the source code for the
doesn’t have the corresponding source class for which the error occurred
code required. exists.

C-6 APTRA Advance ADE, Programmer’s Guide


Build Errors
Final Build Errors

Final Build Errors C

“Error C2501: <GTClassID>: missing decl-specifiers”

Possible Causes Recommended Action

<GTClassID> has not been defined in Check that <ClassID> has been defined
<ClassInclude>. properly in <ClassInclude>.

There is a mismatch between the Check that <GTClassID> is the same as


<GTClassID> defined in the Author the Group Type Class ID defined in
and the one defined in <ClassInclude>. <ClassInclude>.

“Error C2664: Cannot convert from “<ClassID> *” to “<SuperclassID> *”;


Types pointed to are unrelated. Conversion requires reinterpret_cast,
C-style cast or function-style cast”

Possible Causes Recommended Action

You have mistakenly made <ClassID> Remove the Superclass from the
a subclass of the <SuperclassID> in the Worker Class’s Superclass list in the
Author. Author.

APTRA Advance ADE, Programmer’s Guide C-7


Build Errors
Worker Factory Build Errors

Worker Factory Build Errors C

“Error C2559: <ClassID>: cannot instantiate abstract class due to


following members:”

Possible Causes Recommended Action

You have mistakenly defined an Re-enter the Worker Class as an


Abstract Class as a Loner. Abstract.

You have mistakenly defined an Re-enter the Worker Class as an


Abstact Class as a Sequencer. Abstract.

“Error C2039: ‘SetId’: is not a member of ‘<ClassID>’”

Possible Causes Recommended Action

<GTClassID> has not been defined in Check that <ClassID> has been defined
<ClassInclude>. properly in <ClassInclude>.

There is a mismatch between the Check that <GTClassID> is the same as


<GTClassID> defined in the Author the Group Type Class ID defined in
and the one defined in <ClassInclude>. <ClassInclude>.

“Error C2584: ‘<ClassID>’: direct base ‘mConcreteWorker’ is


inaccessible; already a base of ‘<GTClassID>’”

Possible Causes Recommended Action

This Worker Class is inheriting from an Remove mConcreteWorker from the


Abstract that has been mistakenly Abstract Worker Class’s list of base
subclassed from mConcreteWorker. classes in the source code.

C-8 APTRA Advance ADE, Programmer’s Guide


Build Errors
Worker Factory Build Errors

“Error C2039:
‘Remove_<ClassID>::Remove_<GroupTypeID>_WorkGroup(unsigned short)’: is
not a member of <ClassID>”

Possible Causes Recommended Action

The function Remove_<GroupTypeID> Check that the function has been


_WorkGroup has not been defined in defined properly.
<ClassInclude>.

APTRA Advance ADE, Programmer’s Guide C-9


Build Errors
Worker Factory Build Errors

C-10 APTRA Advance ADE, Programmer’s Guide


Table of Contents
Modifying Advance ADE Runtime

Appendix D
Modifying Advance ADE
Runtime

Overview D-1

ASCII/EBCDIC Conversion Functions D-2

APTRA Advance ADE, Programmer’s Guide


Table of Contents
Modifying Advance ADE Runtime

APTRA Advance ADE, Programmer’s Guide


Modifying Advance ADE Runtime
D

Overview

Overview D

Some parts of Advance ADE Runtime can be customised


for your own needs.
This appendix has a list of possible modifications with
descriptions of how to carry them out.

APTRA Advance ADE, Programmer’s Guide D-1


Modifying Advance ADE Runtime
ASCII/EBCDIC Conversion Functions

ASCII/EBCDIC Conversion
Functions D

Advance ADE is supplied with the following conversion


functions:
● ASCIIToEBCDIC()
● EBCDICToASCII()

These functions are described in the APTRA Author on-


line help.
These functions use tables to define ASCII/EBCDIC
conversion. The supplied conversion tables are in the
APTRA Advance ADE, User’s Guide.
If this conversion does not suit your needs, for instance if
you have a different EBCDIC standard, then you can
produce your own customised version to replace the
tables supplied.
This is done by modifying the ASCII/EBCDIC
conversion tables and replacing the supplied DLL as
follows:
1 Edit the file cfuns2.cpp which is the source for the
conversion functions. This file is located in the
<GLOBAL>\FINAL\ULYSSES\SUPPORT\USER
directory.

If you want to change the ASCII to EBCDIC


conversion you have to modify the following array:
unsigned char ASCII_TO_EBCDIC_TABLE []

D-2 APTRA Advance ADE, Programmer’s Guide


Modifying Advance ADE Runtime
ASCII/EBCDIC Conversion Functions

This array has 128 entries; one for each of the ASCII
values. Each entry is the EBCDIC equivalent of the
ASCII value.

So, the following shows the 0x20 entry (all values in


hex) in the table which has an EBCDIC equivalent of
0x40:

0x40, /* 20 Space*/

Similarly, if you want to modify the EBCDIC to


ASCII you change the following array, which has 256
entries:

unsigned char EBCDIC_TO_ASCII_TABLE []

2 Use the supplied makefile cfuns2.mak (in the same


directory as the source) to create the dynamic link
library file cfuns2.dll which replaces the supplied file
in both the <GLOBAL>\FINAL\ULYSSES\DLL and
<GLOBAL>\TEST\DLL directories.

The following is the Visual C++™ Make command


required to build the dll:

nmake /f cfuns2.mak

For the makefile to work properly and overwrite the


existing cfuns2.dll you must make sure that it is not
read only.

APTRA Advance ADE, Programmer’s Guide D-3


Modifying Advance ADE Runtime
ASCII/EBCDIC Conversion Functions

D-4 APTRA Advance ADE, Programmer’s Guide


Table of Contents
Related Documentation

Appendix E
Related Documentation

Overview E-1

Advance ADE Documentation E-2

Other NCR Documentation E-5

APTRA Advance ADE, Programmer’s Guide


Table of Contents
Related Documentation

APTRA Advance ADE, Programmer’s Guide


Related DocumentationE

Overview

Overview E

In this appendix we identify NCR documentation you


may find useful when developing your Advance ADE
application and installing it on an SST.
The documentation is a combination of on-line help files
and Adobe™ Acrobat™ Portable Document Format
(PDF) files. To read the PDF documentation, you need
the Acrobat™ Reader version 3.0 or later.
In general, documentation is provided with its respective
product.

APTRA Advance ADE, Programmer’s Guide E -1


Related Documentation
Advance ADE Documentation

Advance ADE Documentation E

Product Title Format Description

APTRA APTRA Advance ADE, PDF Provides a brief and general


Advance General Description description of Advance ADE.
ADE B006-6035

APTRA Advance ADE, PDF Describes the project management


Organising the Team features provided by Advance ADE
B006-6036 and introduces the different
approaches you can adopt when
developing an Advance ADE
application.

APTRA Advance ADE, PDF Describes the process involved in


Local Language localising elements of the Advance
Customisation Guide ADE user interface.
B006-6037

APTRA Advance ADE, PDF Describes how to install and use the
User’s Guide APTRA Author and Runtime
B006-6038 Components to design, develop
and maintain a self-service
application.

APTRA Advance ADE, PDF Identifies the functionality offered


Seed Application User’s by the Advance ADE Seed
Guide Application and describes how to
B006-6039 use/customise it.

APTRA Advance ADE, PDF Describes how application


Programmer’s Guide programmers should create their
B006-6042 own C++ Worker Classes. It also
contains information on using C
routines to manipulate data.

E-2 APTRA Advance ADE, Programmer’s Guide


Related Documentation
Advance ADE Documentation

Product Title Format Description

APTRA Advance ADE, PDF Provides application programmers


C++ Class Reference with definitions for a number of
B006-6043 C++ Runtime and Utility Worker
Classes provided by NCR.

APTRA Author Help Windows Context-sensitive help for the


Help Author user interface and
authoring errors.

Runtime Core Help Windows Context-sensitive help for the


Help Runtime Core Authoring
components and runtime errors,
which are part of Advance Core
Self-Service.

GUI Help Windows Context-sensitive help for the GUI


Help Authoring components, which are
part of Advance Core Self-Service.

Self-Service Core Help Windows Context-sensitive help for the


Help Self-Service Core Authoring
components, which are part of
Advance Core Self-Service.

ActiveX™ Help Windows Context-sensitive help for the


Help ActiveX™ Authoring components
and runtime errors, which are part
of Advance Core Self-Service.

Basic Self-Service Help Windows Context-sensitive help for the


Help Authoring components provided
with Advance Basic Self-Service.

ATM Help Windows Context-sensitive help for the


Help Authoring components and
runtime errors provided with
Advance ATM.

APTRA Advance ADE, Programmer’s Guide E-3


Related Documentation
Advance ADE Documentation

Product Title Format Description

Special Self-Service Windows Context-sensitive help for the


Help Help Authoring components and
runtime errors provided with
Advance Special Self-Service.

Statement Printer Help Windows Context-sensitive help for the


Help Authoring components and
runtime errors provided with
Advance Statement Printer.

APTRA Passbook Printer Help Windows Context-sensitive help for the


Advance Help Authoring components and
Passbook runtime errors provided with
Advance Passbook Printer.

E-4 APTRA Advance ADE, Programmer’s Guide


Related Documentation
Other NCR Documentation

Other NCR Documentation E

Product Title Format Description

SST Device personaS SST Device Paper This publication describes how to
Simulator Simulator For Windows use the SST Device Simulator to test
NT™, User’s Guide a self-service application under
B006-6041 development.

personaS SST Device Windows Context-sensitive help for the SST


Simulator For Windows Help Device Simulator.
NT™ Help

APTRA Advance ADE, Programmer’s Guide E-5


Related Documentation
Other NCR Documentation

E-6 APTRA Advance ADE, Programmer’s Guide


Glossary

APTRA Advance ADE, Programmer’s Guide


APTRA Advance ADE, Programmer’s Guide
Glossary

Glossary

abstract A class that can only be used as a superclass for


A other classes. An object of this class cannot be created.
activation The state of a Doer Worker when it is started.
Application An application that has been developed
using the APTRA Author, containing Workers and Work
Groups, which carries out some task.
ASCIIZ An array of ASCII characters terminated by a
null character.
Author The software tool used to develop Applications.
It supports the creation, editing and testing of
Applications.

Basic Work Group This type of Work Group can contain


B all Workers that are not Doers. The Work Group is an
instance of the mBasicWorkGroup class template.

cardholder The SST customer.


C
Class ID The unique class identifier assigned to each
class as it is introduced into the Author.
Component ID A variable length string that has a unique
value for all the components in the environment.
Concrete Worker A concrete Worker Class is one that can
be instantiated. To work correctly in the Advance ADE
environment a concrete Worker Class must be a subclass
of the mConcreteWorker class.

APTRA Advance ADE, Programmer’s Guide Glossary-1


Glossary

Coordinator A type of Worker which can coordinate the


work of Subworkers contained in one or more Work
Groups.

deactivation The state an active Worker goes into when it


D is stopped.
delete When used in reference to objects, this term
implies that the object has been completely cleared from
memory; compare with remove.
DLL A Dynamic Link Library, that is a library that can
be linked at execution time.
Doer A Worker Class that can be activated, deactivated
and can also process events. A Worker Class must be a
subclass of mDoer to be a Doer.
Doer Work Group This type of Work Group can contain
only Doer Workers. The Work Group is an instance of
the mDoerWorkGroup class template.

Event An occurrence in the SST system that the software


E must handle. Events are encapsulated in a C++ object
which is a subclass of the mEvent class.
Event Context This defines the context in which the
Workers get and receive events. See mEventContext
class.
Event ID The unique identifier associated with each
event.
Event processing The process whereby a Doer Worker
handles an event.
Event Queue The queue that events are posted to and
taken from.

Glossary-2 APTRA Advance ADE, Programmer’s Guide


Glossary

Getter The name of the Worker Classes that can give


G data. This Worker is a subclass of the class mGetter.

Handle This is used to allow Advance ADE classes to


H have access to external data types. See the mHandle
class.
Handle Getter A Worker that can return a handle. This
Worker must be a subclass of the mHandleGetter class.
Handle ID A unique identifier assigned to each of the
external data types.
Handle Putter A Worker that can accept a handle. This
Worker must be a subclass of the mHandlePutter class.

IDE Interactive Development Environment


I
instantiated When an instance of a class is created it is
said that the object has been instantiated.
Integer Getter A Worker that can return an integer. This
Worker must be a subclass of the mIntegerGetter class.
Integer Putter A Worker that can accept an integer. This
Worker must be a subclass of the mIntegerPutter class.

late signal A signal sent by a Worker which received a


L late event.
late event An event that a Worker got from the event
queue while it was deactivating.

mString An object that can contain many forms of


M characters in different forms of arrays. It is defined by
the mString class.

APTRA Advance ADE, Programmer’s Guide Glossary-3


Glossary

parent The name given to the object that is higher up in a


P hierarchical structure than the child object.
Putter A Worker Class that can receive data.
priority see Signal Priority.

remove When used in reference to objects, implies that


R only a reference to the object has been removed, and the
object remains in memory. Also see delete.
Real Getter A Worker that can return a real. This Worker
must be a subclass of the mRealGetter class.
Real Putter A Worker that can accept a real. This Worker
must be a subclass of the mRealPutter class.

Self-Service Support A 32-bit open software platform


S supplied by NCR for use on SSTs.
sharing The name given to the way objects share data,
rather than repeating the same data when a copy is made
of it. If changes are made to shared data, the other objects
sharing the data automatically get the modified data.
Signal Generated by a doer Worker to indicate to its
coordinator that something has occurred. It is an
instance of the mSignal class.
Signal ID The signal identifier (ID) is used to differentiate
between different signals from the same object.
Signaller The name given to any Worker that can
generate a signal, and that is a subclass of the mSignaller
class.
Signal Priority Used to differentiate between signals by
their importance. A high priority signal is more
important than a low one, and has to be handled more

Glossary-4 APTRA Advance ADE, Programmer’s Guide


Glossary

quickly. The exact meaning of the different priorities is


defined by the SignalPriorityRef data type, defined
in the APTRA Advance ADE, C++ Class Reference.
SST Self Service Terminal.
string A null terminated character array.
String Getter A Worker that can return an mString. This
Worker must be a subclass of the mStringGetter class.
String Putter A Worker that can accept an mString. This
Worker must be a subclass of the mStringPutter class.
Subworker The term given to any worker that is in a
Work Group. It is said to be a Subworker of the
Coordinator of the Work Group.
Superclass A class from which another class inherits.

thread A line of execution in a process. See the operating


T system documentation for more information.

User Event An event produced by the user’s own code.


U This in an instantiation of the mUserEvent class.
User Message The message contained with the User
Event. This is normally defined by the UserMsg
structure.

Work Context The name given to the list of Work Groups


W an event must pass through to get to a particular Worker.
An instantiation of the mWorkContext class.
Work Group A group of Workers that are all executed
concurrently. This must be a subclass of the
mWorkGroup class.

APTRA Advance ADE, Programmer’s Guide Glossary-5


Glossary

Worker The name given to the different objects that can


be executed in a Application.
Worker Class The name given to classes that have been
introduced into the Author environment.

Glossary-6 APTRA Advance ADE, Programmer’s Guide


Index

APTRA Advance ADE, Programmer’s Guide


APTRA Advance ADE, Programmer’s Guide
Index

Index 0

56XX SST 1-1


Numerics
Abstract Advance ADE Metaclass 7-3, 7-15
A Abstract Worker Class 7-23
Attribute Types 8-2
deciding if the class is an Abstract 7-15
example Worker Class
Base String 10-6
Convert to Upper subclass of Base String 10-6
implementation 8-2
inheritance guidelines 7-23
activation hierarchy 6-2
Add_X_WorkGroup
member function of the Work Group Interface
see Work Group Type : Work Group Interface
AddWorker
use of 8-52
ADI-2 1-1–1-2
blocking calls A-3
channels A-3
non-blocking calls A-3
resources A-4
services A-3
ADI-2 Extensions
ADI_M_SETUP_MONITOR A-3
ADI-2 Functions
ADI_ATTACH A-4
ADI_DETACH A-4
ADI_INITIALISE A-4–A-5
ADI_LOOKUP_NAME A-5
ADI_RECEIVE A-5
ADI_RECEIVE_EVENT A-3–A-5
ADI_REMOVE_MONITOR A-4–A-5
ADI_SEND A-5

APTRA Advance ADE, Programmer’s Guide Index-1


Index

ADI_SETUP_MONITOR A-3
ADI_TERMINATE A-4–A-5
ADI-2 Interfacing
example of a Worker Class using ADI-2 calls
Eject Card 10-5
introduction A-2
when to use the interface A-2
Advance ADE Data Types
see also data types 4-3
Advance ADE Metaclasses 7-3
Abstract 7-3
Grapher 7-4
Loner 7-4
Sequencer 7-4
Advance ADE Runtime
modifying D-1
Advance ADE System
description 8-3
Advance ADE Worker Classes 3-2
Application
data transfer in the Application 6-3
Application Layer of the Self Service Terminal Software 1-1
ASCIIZ string 4-26
Assigner Worker 4-2
parsing data using an external C function 5-16
Attribute Type 7-6
example implementation 7-27
class and function definition 7-29
example of use in the Worker Class, Trace 10-4
identify new Attribute Types 7-7
default value 7-10
description 7-10
ID 7-8
Link 7-10
Literal Type 7-8
Enumerated 7-9
File Reference 7-9
Float 7-9
Integer 7-9
Point 7-9

Index-2 APTRA Advance ADE, Programmer’s Guide


Index

String 7-9
Name 7-8
implementing 7-25
defining the default value 7-25
note on responsibility for the declaration 7-26
return type 7-26
the Attribute method 7-25
defining the name 7-25
defining the parameters 7-25
example declaration 7-25
using the Attribute ID 7-25
Author Worker Class Definition 7-2, 9-7

BASIC Expressions
B comparison with other types of Runtime extension 3-5
_beginthread
Borland OS/2 C++ Function see thread 8-12
BroadcastEvent
use of 8-43
BroadcastEvent Message 6-4
BroadcastStart
use of 8-41
BroadcastStart Message 6-4
BroadcastStop
use of 8-45
BroadcastStop Message 6-4
build errors
final build C-1
Worker Factory C-1
Build Factory 9-7–9-8

calculations using external C functions 5-4


C char C/C++ data type 4-9
equivalent Advance ADE Data Type, String 4-8
equivalent Registration Keyword, char 4-26
char* C/C++ data type
equivalent Advance ADE Data Type, String 4-8
equivalent Registration Keyword, char ByRef 4-27
equivalent Registration Keyword, string 4-26

APTRA Advance ADE, Programmer’s Guide Index-3


Index

char** C/C++ data type


equivalent Registration Keyword, string ByRef 4-27
common bases 7-23
Comparison of the different types of Advance ADE Runtime
extension 3-4
Computer Worker 4-2
Concrete Worker
Class Name of mConcreteWorker 7-23
concurrency 7-15
making a Worker Class handle it 7-3
concurrent activation 6-4
Control Messages 6-2
coordinates using the Point Literal Type 7-9
Coordinator 6-2
Coordinator Worker Class
Grapher 7-4
Sequencer 7-4

Data Messages 6-5


D Get 6-6
Put 6-6
data testing using an external C function 5-8
data types
Advance ADE 4-3
C/C++ 4-4
external 4-9
external C function Advance ADE Data Types and their
associated C/C++ data type 4-7
Registration Entry for external C functions 4-25
table of Advance ADE Data Types and their C/C++
equivalents 4-7
table of Literal Types and C++ Equivalents 7-26
user defined 4-9
debugging
application B-1
external function 4-34
Worker Class 9-12
devices 8-3
direct inheritance 7-16

Index-4 APTRA Advance ADE, Programmer’s Guide


Index

Director Worker Class 7-4


directories
<GLOBAL>
files
initial USERFUNS.SCR 4-16
<GLOBAL>\TEMP
files
temporary Build Factory files C-1
Do Messages 7-6
Process Event 6-4
Start 6-4
Stop 6-4
Doer 6-3, 7-6, 8-38
activation
use of the Start member function 8-8
activation process for each Doer type 8-8
as a Getter or Putter Coordinator 7-17
data members
important note about initialization 8-7
deactivation
use of the Stop member function 8-17
deactivation process for each Doer type 8-16
default Event handler see EventDefault 8-13
Event process for each Doer type 8-13
every Doer is a subclass of mDoer 8-3
example of a subclass declaration 8-6
execution sequence 8-6
execution time limits 8-3
implementing
a second thread see thread 8-21
implementing a subclass 8-3
types
Event Signaller, see Event Signaller Doer 8-5
Multi-Thread Signaller see Multi-Thread Doer 8-5
Simple see Simple Doer 8-4
Simple Signaller see Simple Signaller Doer 8-4
processing events
use of the ProcessEvent member function 8-13
Signal generation
during event processing 8-13

APTRA Advance ADE, Programmer’s Guide Index-5


Index

late Signals during deactivation 8-17


none on activation 8-8
Doer Coordinator 6-4, 8-8, 8-13, 8-17
activation
activating the Subworkers using the BroadcastStart
method 8-41
example implementation 8-42
process 8-41
using the Start member function 8-40–8-41
as a Signal Consumer 8-39
can also be a Getter or Putter Coordinator 7-17, 8-38
collating Signals 8-39
data members
important note about initialization 8-41
deactivation
example implementation 8-45
process 8-44
signal consuming 8-45
using the Stop member function 8-40, 8-44
event processing 8-42
example implementation 8-44
signal consuming 8-43
use of the ProcessEvent member function 8-43
execution sequence 8-40
execution sequence of Subworkers 8-42
implementing the Doer Work Group 8-51
implementing the Worker Class 8-38
processing events
using the ProcessEvent member function 8-40
subclass of mDoer 8-38
Work Group and Subworker limits 8-38
Doer Work Group 6-4
double C/C++ data type 7-9, 8-29, 8-35
equivalent Advance ADE Data Type, Real 4-7
equivalent Literal Type, Float 7-26
equivalent Registration Keyword, double 4-26
double* C/C++ data type
equivalent Advance ADE Data Type, Real 4-7
equivalent Registration Keyword, double ByRef 4-27

Index-6 APTRA Advance ADE, Programmer’s Guide


Index

enum C/C++ data type 7-9


E equivalent Literal Type, Enumerated 7-26
Enumerated Literal Type 7-9, 7-19
C++ equivalent, enum 7-26
implementation notes 7-26
list of enumerated values 7-19
Name 7-19
error messages
common build errors C-5
Error Loading DLL 4-24
Error Loading Function 4-24
final build errors C-7
Invalid Name 4-4
Type Mismatch 4-12, 8-31
Value Out Of Range 4-8
worker factory build errors C-8
Event 8-14, 8-43
late 8-5
processing 6-4
Event Context 8-12, 8-22
Event Queue 8-8, 8-10, 8-13, 8-17, 8-24
Event Signaller Doer 8-5
example Worker Class
Eject Card 10-5
EventDefault
mDoer member function
use in the mDoer ProcessEvent member function 8-13
extending the Advance ADE Runtime
when to extend 3-3
ways of extending 3-4
BASIC Expressions 3-5
external C functions 3-6
external C functions 4-1, 5-1, A-3
Advance ADE String Type conversion to char or char*
character test 4-9
building a DLL 4-20
building the DLL
what is required when using mString 4-22
comparison with other types of Runtime extension 3-6

APTRA Advance ADE, Programmer’s Guide Index-7


Index

development
building
DLL file location 4-15
debugging 4-34
design 4-3
implementation 4-17
registration
Registery File location 4-15
responsibility for registering 4-23
testing 4-31
using harness 4-31
using test Application 4-31
development introduction 4-2, 5-2
directory figure 4-15
example of function syntax 4-3
examples
Assigner Worker 5-16, 5-24
Computer Worker 5-4
Handle Store Worker 5-24
location of examples
figure 5-3
Selector Worker 5-12
Tester Worker 5-8
exporting function from DLL 4-17
external data type 4-9
example of function syntax 4-11
example of use 5-24
registering 4-28
using a Handle 4-10
using a String 4-10
function syntax 4-3
memory allocation and deallocation 4-12
naming convention 4-3
function alias 4-4
functions 4-3
naming conventions
function parameters 4-5
parameters and return types
values and references use same Advance ADE Data
Type 4-8

Index-8 APTRA Advance ADE, Programmer’s Guide


Index

Registery File location


figure 4-15
Registration Entry
Alias Name 4-24
Argument Type List 4-25
Data Types 4-25
char 4-26
char ByRef 4-27
double 4-26
double ByRef 4-27
example 4-27
external data type 4-28
float 4-26
float ByRef 4-27
integer 4-26
integer ByRef 4-27
ldouble 4-26
ldouble ByRef 4-27
long 4-26
long ByRef 4-27
mstring 4-26
mstring ByRef 4-27
short 4-26
short ByRef 4-27
string 4-26
string ByRef 4-27
uchar 4-26
uchar ByRef 4-27
uinteger 4-26
uinteger ByRef 4-27
ulong 4-26
ulong ByRef 4-27
ushort 4-26
ushort ByRef 4-27
DLL Name 4-24
example Entry 4-25
example Entry for an external data type 4-28
format of Entry 4-23
Function Name 4-24
Keyword

APTRA Advance ADE, Programmer’s Guide Index-9


Index

passing by reference 4-26


passing by value 4-26
plus ’ByRef’ 4-26
Return Type 4-24
table of Keyword ByRefs against C/C++ data
types 4-27
table of Keywords against C/C++ data types 4-26
stages of the development process 4-2
table of Advance ADE Data Types and C/C++
equivalents 4-7
testing 4-18
troubleshooting 4-35
use of external C functions
calculations 5-4
Signal generation 5-12
using mString 4-9
external data type 4-4, 8-27, 8-33
equivalent Advance ADE Data Type, Handle 4-8
example of use by an external C function 5-24
use in external functions 4-9
Worker Class
processing by 8-36
production by 8-30
external libraries 3-6

file locations
F external C function DLL 4-15
initial blank USERFUNS.SCR 4-16
out.txt Build Factory error file C-1
USERFUNS.SCR 4-16
wcexam1.mak used to automate the Worker Class build
process 9-3
Worker Class examples 10-2
File Reference Literal Type 7-9, 7-20
class equivalent, mString& 7-26
default extension 7-20
description 7-20
implementation notes 7-27
Name 7-20

Index-10 APTRA Advance ADE, Programmer’s Guide


Index

final application
build errors C-1
building 9-8
float C/C++ data type
equivalent Advance ADE Data Type, Real 4-7
equivalent Registration Keyword, float 4-26
Float Literal Type 7-9, 7-20
C++ equivalent, double 7-26
description 7-20
minimum and maximum value 7-20
Name 7-20
significant digits 7-20
float* C/C++ data type
equivalent Advance ADE Data Type, Real 4-7
equivalent Registration Keyword, float ByRef 4-27

Get
G Data Message 6-6, 7-6, 8-26
GetNumWorkers
mTBasicWorkGroup member function 8-47, 8-49
use of 8-52
Getter 7-6
as a Getter or Putter Coordinator 7-17
data conversions 8-27, 8-33
diagram of the class hierarchy 8-27, A-5
implementing a subclass 8-26
mHandleGetter see mHandleGetter Worker
Class 8-29
mIntegerGetter see mIntegerGetter Worker Class 8-29
mRealGetter see mRealGetter Worker Class 8-28
mStringGetter see mStringGetter Worker Class 8-28
Worker Class ID 8-52
Getter Coordinator
can also be a Putter or Doer Coordinator 7-17
example of getting data from a Getter Subworker 8-48
example Worker Class
Date Setter 10-4–10-5
String Searcher 10-5
getting the address of a Subworker using GetWorker 8-47

APTRA Advance ADE, Programmer’s Guide Index-11


Index

getting the number of Subworkers using


GetNumWorkers 8-47
implementing the Getter Work Group 8-51
implementing the Worker Class 8-47
Work Group and Subworker limits 8-47
Getter Work Group 8-47
GetWorker
mTBasicWorkGroup member function 8-47, 8-49
use of 8-52
Grapher Advance ADE Metaclass 7-4

Handle Advance ADE Data Type


H type-declaration suffix ’?’ 4-8
Handle Giver
Class Name of mHandleGetter 8-30
Handle Receiver
Class Name of mHandlePutter 8-35
Handle Store Worker 5-24

inheritance
I direct 7-16
indirect 7-16
int C/C++ data type 4-8
equivalent Advance ADE Data Type, Integer 4-7
equivalent Registration Keyword, integer 4-26
int* C/C++ data type 4-8
equivalent Advance ADE Data Type, Integer 4-7
equivalent Registration Keyword, integer ByRef 4-27
Integer Advance ADE Data Type
equivalent C/C++ types
int 4-7
int* 4-7
long 4-7
long* 4-7
short 4-7
short* 4-7
unsigned int 4-7
unsigned int* 4-7
unsigned long 4-7

Index-12 APTRA Advance ADE, Programmer’s Guide


Index

unsigned long* 4-7


unsigned short 4-7
unsigned short* 4-7
type-declaration suffix ’%’ 4-7
integer ByRef Registration Keyword
equivalent C/C++ type, int* 4-27
Integer Calculator Worker 5-13
Integer Giver
Class Name of mIntegerGetter 8-29
Integer Literal Type 7-9, 7-21
C++ equivalent, long 7-26
description 7-21
minimum and maximum 7-21
name 7-21
Integer Receiver
Class Name of mIntegerPutter 8-35
integer Registration Keyword
equivalent C/C++ type, int 4-26

ldouble ByRef Registration Keyword


L equivalent C/C++ type, long double* 4-27
ldouble Registration Keyword
equivalent C/C++ type, long double 4-26
Literal Type 7-19, 7-25
Enumerated 7-9, 7-19
C++ equivalent, enum 7-26
File Reference 7-9, 7-20
class equivalent, mString& 7-26
Float 7-9, 7-20
C++ equivalent, double 7-26
How to define new ones 7-19
Integer 7-9, 7-21
C++ equivalent, long 7-26
Point 7-9, 7-21
C++ equivalent, long, long 7-26
String 7-9, 7-22
class equivalent, mString& 7-26
table of Literal Types and C++ Equivalents 7-26
use as an Attribute Type 7-8

APTRA Advance ADE, Programmer’s Guide Index-13


Index

Loner Advance ADE Metaclass 7-4, 7-16


Loner Worker 6-2
Loner Worker Class
is the class a Loner 7-16
long C/C++ data type 7-9, 8-29, 8-35
equivalent Advance ADE Data Type, Integer 4-7
equivalent Literal Type, Integer 7-26
equivalent Registration Keyword, long 4-26
long double C/C++ data type
equivalent Advance ADE Data Type, Real 4-7
equivalent Registration Keyword, ldouble 4-26
long double* C/C++ data type
equivalent Advance ADE Data Type, Real 4-7
equivalent Registration Keyword, long double ByRef 4-27
long* C/C++ data type
equivalent Advance ADE Data Type, Integer 4-7

mConcreteWorker class 7-23, 8-41


M note on class type 7-7
mcore.h
Advance ADE Runtime include file 7-24
mDoer Worker Class 7-15, 7-23, 8-3, 8-38, 8-40
member functions
EventDefault see EventDefault 8-13
ProcessEvent see ProcessEvent 8-6
Start see Start 8-6
Stop see Stop 8-6
Message Types 7-6
choosing which Message Types to use 7-5
Do 7-6
Get 7-6
Put 7-6
mEvent class
use by the mDoer ProcessEvent member function 8-13
use in a Doer declaration 8-7
mEventContext class
use in a Doer declaration 8-7
use in the mDoer ProcessEvent member function 8-13,
8-15

Index-14 APTRA Advance ADE, Programmer’s Guide


Index

use in the mDoer Start member function 8-8, 8-10


use in the mDoer Stop member function 8-17, 8-19
use in the mDoer thread member function 8-24
mGetter Worker Class
Class ID of Getter 8-26
mHandle class 4-4
mHandle Worker Class 8-30, 8-36
mHandleGetter
Class ID of Handle Giver 8-30
Class ID of Handle Receiver 8-35
mHandleGetter Worker Class
implementing 8-29
position in Getter hierarchy 8-27
mHandlePutter Worker Class
example Worker Class
Convert Handle TM 10-6
implementing 8-35
position in Putter hierarchy 8-33
mIntegerGetter
Class ID of Integer Giver 8-29
mIntegerGetter Worker Class
implementing 8-29
position in Getter hierarchy 8-27
mIntegerPutter
Class ID of Integer Receiver 8-35
mIntegerPutter Worker Class
implementing 8-35
position in Putter hierarchy 8-33
modifying the Advance ADE Runtime D-1
mPutter Worker Class
Class ID of Putter 8-32
mRealGetter Worker Class
Class ID of Real Giver 8-29
implementing 8-28
position in Getter hierarchy 8-27
mRealPutter Worker Class
Class ID of Real Receiver 8-34
implementing 8-34
position in Putter hierarchy 8-33
mSignal class

APTRA Advance ADE, Programmer’s Guide Index-15


Index

Class ID of Signal 8-16, 8-20


use in a Doer declaration 8-7
use in the mDoer ProcessEvent member function 8-15
use in the mDoer Stop member function 8-19
mstring ByRef Registration Keyword
equivalent Advance ADE Class ID, mString* 4-27
mString class 8-28, 8-34
equivalent Advance ADE Data Type, String 4-8
equivalent Registration Keyword, mstring 4-12, 4-26
use in an external function 4-9
mstring Registration Keyword
equivalent Advance ADE Class ID, mString 4-26
mString& class
equivalent Literal Type
String 7-26
mString* class
equivalent Advance ADE Data Type, String 4-8
equivalent Registration Keyword, mstring ByRef 4-27
mStringGetter Worker Class
Class ID of String Giver 8-28
example of using mStringGetter as a Subworker 8-48
example Worker Class
Convert To Upper 10-6
System Time 10-4
implementing 8-28
position in Getter hierarchy 8-27
mStringPutter Worker Class
Class ID of String Receiver 8-34
example of using mStringPutter as a Subworker 8-50
example Worker Class
Base String 10-6
System Time 10-4
implementing 8-34
position in Putter hierarchy 8-33
mTBasicWorkGroup template class
creating a Getter Work Group Type 8-52
creating a Putter Work Group Type 8-53
example of creating
a new Getter Work Group Type 8-53
a new Putter Work Group Type 8-54

Index-16 APTRA Advance ADE, Programmer’s Guide


Index

instantiating the template 8-52, 8-54


member functions
AddWorker 8-52
Constructor 8-52
GetNumWorkers 8-52
GetWorker 8-52
RemoveWorker 8-52
mTDoerWorkGroup template class
creating a Doer Work Group Type 8-54
example of creating
a new Doer Work Group Type 8-55
member functions
BroadcastEvent 8-43
BroadcastStart 8-41
BroadcastStop 8-45
Constructor 8-54
note about using mDoer as the template parameter 8-55
use in Doer Coordinator 8-41, 8-43
multi-tasking 1-2
Multi-Thread Signaller Doer 8-5
activation
Start method 8-11
Start method example 8-12
deactivation
Stop method 8-21
example Worker Class
String Searcher 10-5
implementing a second thread see thread 8-21
processing Events
ProcessEvent method 8-16
mUserEvent class
use in the mDoer ProcessEvent member function 8-15
use in the mDoer Start member function 8-10
use in the mDoer Stop member function 8-19
use in the mDoer thread member function 8-24
mWorkContext class
use in a Doer declaration 8-7

APTRA Advance ADE, Programmer’s Guide Index-17


Index

NVRAM 1-2
N
out.txt
O Build Factory error file C-1

parsing data using an external C function 5-16


P Pass Thru Worker 5-8, 5-12
PC Development Environment 2-2
Software Requirements 2-2
Point Literal Type 7-9, 7-21
C++ equivalent, long, long 7-26
description 7-21
implementation notes 7-27
minimum and maximum X-value 7-21
minimum and maximum Y-value 7-21
name 7-21
Process Event
Do Message 6-4
ProcessEvent
mDoer member function 8-6
use in a Coordinator 8-43
use in a Loner 8-13
Put
Data Message 6-6, 7-6, 8-32
Putter 7-6
as a Getter or Putter Coordinator 7-17
Class Name of mPutter Worker Class 8-32
diagram of the class hierarchy 8-33
implementing a subclass 8-32
mHandlePutter see mHandlePutter Worker Class 8-35
mIntegerPutter see mIntegerPutter Worker Class 8-35
mRealPutter see mRealPutter Worker Class 8-34
mStringPutter see mStringPutter Worker Class 8-34
Worker Class ID 8-53
Putter Coordinator
can also be a Getter or Doer Coordinator 7-17
example of giving data to a Putter Subworker 8-50
example Worker Class

Index-18 APTRA Advance ADE, Programmer’s Guide


Index

Convert Handle TM 10-6


Date Getter 10-4
getting the address of a Subworker using GetWorker 8-49
getting the number of Subworkers using
GetNumWorkers 8-49
implementing the Putter Work Group 8-51
implementing the Worker Class 8-49
Work Group and Subworker limits 8-49
Worker Type restriction 8-49
Putter Work Group 8-49, 8-51

Real Advance ADE Data Type


R blank type-declaration suffix 4-7
equivalent C//C++ types
long double 4-7
equivalent C/C++ types
double 4-7
double* 4-7
float 4-7
float* 4-7
long double* 4-7
Real Computer Worker 5-4
Real Giver
Class Name of mRealGetter 8-29
Real Receiver
Class Name of mRealPutter 8-34
Registration Entry
Data Types for external C functions 4-25
Keywords and equivalent C/C++ Types 4-26
Keywords ByRef and equivalent C/C++ data types 4-27
Remove_X_WorkGroup
member function of the Work Group Interface
see Work Group Type : Work Group Interface
RemoveWorker
use of 8-52
Runtime
Advance ADE 7-23
include file mcore.h 7-24

APTRA Advance ADE, Programmer’s Guide Index-19


Index

Self Service Terminal Software 1-1


S Self-Service Support Layer 1-2
semaphore 1-2, 8-3
Sequencer Advance ADE Metaclass 7-4, 7-17
Sequencer Worker Class
is the class a Sequencer 7-17
sequential controller
description 7-17
short C/C++ data type
equivalent Advance ADE Data Type, Integer 4-7
equivalent Registration Keyword, short 4-26
short* C/C++ data type
equivalent Advance ADE Data Type, Integer 4-7
equivalent Registration Keyword, short ByRef 4-27
Signal 6-2, 6-4, 7-23, 8-8, 8-13, 8-39, 8-43
Class Name of mSignal 8-16, 8-20
ID 8-16, 8-20
late 8-5, 8-17, 8-39, 8-44–8-45
Priority 8-16
InternalEventPriority 8-20
Signal Consumer 7-10, 7-12, 8-39, 8-43, 8-45
Signal generation using an external C function 5-12
Signal Types
decide which are generated 7-15
Name 7-16
description 7-16
ID 7-16
Simple Doer 8-4
activation
Start method 8-9
Start method example 8-9
deactivation
Stop method 8-18
Stop method example 8-18
example Worker Class
Date Getter 10-4
Date Setter 10-4
Trace 10-4
processing Events

Index-20 APTRA Advance ADE, Programmer’s Guide


Index

ProcessEvent method 8-14


ProcessEvent method example 8-14
Simple Signaller Doer 8-4
activation
Start method 8-9
Start method example 8-10
deactivation
Stop method 8-18
Stop method example 8-19
example Worker Class
Simple Signaller 10-4
processing Events
ProcessEvent method 8-14
ProcessEvent method example 8-15
Software Requirements
to run the PC Development Environment 2-2
SST 8-3
Start
Do Message 6-4
mDoer member function 8-6
use in a Coordinator 8-41
use in a Loner 8-8
Stop
Do Message 6-4
mDoer member function 8-6
use in a Coordinator 8-44
use in a Loner 8-17
String Advance ADE Data Type
equivalent C/C++ types
char 4-8
char * 4-8
mString 4-8
mString* 4-8
unsigned char 4-8
unsigned char* 4-8
type-declaration suffix ’$’ 4-8
string ByRef Registration Keyword
equivalent C/C++ type, char** 4-27
String Giver
Class Name of mStringGetter 8-28

APTRA Advance ADE, Programmer’s Guide Index-21


Index

String Literal Type 7-9, 7-22


class equivalent, mString& 7-26
description 7-22
maximum length 7-22
name 7-22
String Receiver
Class Name of mStringPutter 8-34
string Registration Keyword
equivalent C/C++ type, char * 4-26
Subworker 6-2, 6-4
suffix used for type-declaration 4-5
Superclasses 7-5
choosing which Worker Classes to inherit from 7-6

test application
T for testing external C functions 4-31
troubleshooting 9-13
test harness
for testing external C functions 4-31
Tester Worker 4-2
example of data testing using an external C function 5-8
testing data using an external C function 5-8
thread 8-3
for a Worker Class that handles multiple threads see the
Multi-Thread Signaller Doer 8-5
implementing a second thread 8-21
example declaration of a thread function 8-22
example implementation of a thread function 8-24
minimum stack size 8-21
sending a User Event after the Doer is deactivated 8-21
starting the thread
example code 8-12
use _beginthread see also _beginthread 8-12
thread parameter structure
declaring the structure 8-22
initializing the values 8-12
using the values 8-24
main Application 8-41, 8-43, 8-45
main Application thread A-3

Index-22 APTRA Advance ADE, Programmer’s Guide


Index

Top Worker 6-2, 6-4


troubleshooting
external functions 4-35
Worker Classes 9-13
type-declaration suffix 4-4

uchar ByRef Registration Keyword


U equivalent C/C++ type, unsigned char* 4-27
uchar Registration Keyword
equivalent C/C++ type, unsigned char 4-26
uinteger ByRef Registration Keyword
equivalent C/C++ type, unsigned int* 4-27
uinteger Registration Keyword
equivalent C/C++ type, unsigned integer 4-26
ulong ByRef Registration Keyword
equivalent C/C++ type, unsigned long* 4-27
ulong Registration Keyword
equivalent C/C++ type, unsigned long 4-26
UNICODE 4-12
unsigned char C/C++ data type 4-9
equivalent Advance ADE Data Type, String 4-8
equivalent Registration Keyword, uchar 4-26
unsigned char* C/C++ data type
equivalent Advance ADE Data Type, String 4-8
equivalent Registration Keyword, uchar ByRef 4-27
unsigned int C/C++ data type
equivalent Advance ADE Data Type, Integer 4-7
equivalent Registration Keyword, uinteger 4-26
unsigned int* C/C++ data type
equivalent Advance ADE Data Type, Integer 4-7
equivalent Registration Keyword, uinteger ByRef 4-27
unsigned long C/C++ data type
equivalent Advance ADE Data Type, Integer 4-7
equivalent Registration Keyword, ulong 4-26
unsigned long* C/C++ data type
equivalent Advance ADE Data Type, Integer 4-7
equivalent Registration Keyword, long ByRef 4-27
equivalent Registration Keyword, ulong ByRef 4-27
unsigned short C/C++ data type

APTRA Advance ADE, Programmer’s Guide Index-23


Index

equivalent Advance ADE Data Type, Integer 4-7


equivalent Registration Keyword, ushort 4-26
unsigned short* C/C++ data type
equivalent Advance ADE Data Type, Integer 4-7
equivalent Registration Keyword, ushort ByRef 4-27
User Event 8-4, 8-8, 8-13, 8-22, 8-24, 8-43
late 8-5
User Message 8-10, 8-25
USERFUNS.SCR registry file 4-16, 4-23
UserMsg
data type
use in the mDoer ProcessEvent member function 8-15
use in the mDoer Start member function 8-10
use in the mDoer Stop member function 8-19
ushort ByRef Registration Keyword
equivalent C/C++ type, unsigned short* 4-27
ushort Registration Keyword
equivalent C/C++ type, unsigned short 4-26

Visual C++(TM) compiler 2-2


V
Work Group 3-8, 6-2
W Work Group Type
adding a Subworker 8-52
get the number of Subworkers 8-52
getting a pointer to a Subworker 8-52
Group Type Class ID 8-53, 8-55, 8-59, 8-61
Group Type Id
implementing 8-59
identify new Work Group Types 7-10
description 7-11, 7-13
Doer Subworkers 7-12
Getter Subworkers 7-12
Group Name 7-10–7-11
Group Type Class ID 7-10, 7-13
Group Type ID 7-10–7-11
maximum Subworkers 7-11, 7-13
maximum Work Groups 7-10, 7-13
Message Types 7-10–7-11

Index-24 APTRA Advance ADE, Programmer’s Guide


Index

minimum Subworkers 7-10, 7-13


Putter Subworkers 7-12
Signal Consumer 7-10, 7-12
Subworker Class 7-10–7-11
implementing 8-51
a Doer Work Group
see mTDoerWorkGroup template class 8-54
a Getter or Putter Work Group
see mTBasicWorkGroup template class 8-52
declaring the Work Group Interface 8-58
Add_X_WorkGroup member function 8-58–8-59,
8-61
example declaration 8-59
format of the declaration 8-58
Remove_X_WorkGroup member function 8-58,
8-60, 8-62
declaring the Work Group Type 8-56
example code for a multiple Work Group 8-57
example code for a single Work Group 8-56
for a multiple Work Group 8-57
for a single Work Group 8-56
note on responsibility for the declaration 8-57
the multiple Work Group Interface 8-61
example implementation 8-62
the single Work Group Interface 8-59
example implementation 8-61
removing a Subworker 8-52
stages of the implementation 8-51
Work Group ID 8-59, 8-62
Work Group Interface 8-51
Work Group pointer type 8-53, 8-55
note on use 8-56
Worker 3-2, 6-2, 8-3
Worker Class
Abstract 7-15
Abstract Worker Class 8-2
Attribute Types 7-7
Class ID 7-13
Class Name 7-13
concurrency 7-15

APTRA Advance ADE, Programmer’s Guide Index-25


Index

making a Worker Class handle it 7-3


debugging 9-12
description 7-14
design process 7-5
can the Worker Class handle concurrency 7-15
choose a Class ID 7-13
choose a Class Name 7-13
choosing Message Types 7-5
Do 7-6
Get 7-6
Put 7-6
decide if a new Icon us required 7-14
decide if the Metaclass is Loner 7-16
decide if the Metaclass is Sequencer 7-17
is it a Doer Coordinator 7-17
is it a Getter Coordinator 7-17
is it a Putter Coordinator 7-17
decide on the Superclasses 7-6
decide what Signal Types are generated 7-15
description 7-16
Signal ID 7-16
Signal Name 7-16
describe the Worker Class 7-14
identify new Attribute Type
see Attribute Type : identify new Attribute
Types 7-7
identify new Work Group Types see Work Group Type
: identify new Work Group Types 7-10
development
adding it to the Advance ADE Runtime 9-5
building a subclass of a Worker Class 9-4
building the DLL 9-3
automating the build process using make files 9-3
debugging 9-12
design
see Worker Class : design process 7-5
use of Work Groups 7-2
implementing
a Doer Coordinator see Doer Coordinator 8-38
a Doer see Doer 8-3

Index-26 APTRA Advance ADE, Programmer’s Guide


Index

a Getter see Getter 8-26


a Putter, see Putter 8-32
a Work Group Type see Work Group Type 8-51
an Abstract Worker Class, see also Abstract Worker
Class 8-2
an Attribute Type see Attribute Type
implementing 7-25
guidelines 7-23
overview 6-1, 7-1, 8-1, 9-1
removing it from the Advance ADE Runtime 9-8
testing 9-9
Doer 8-3
Doer Coordinator 8-38
examples
Base String
Abstract String Receiver, Attribute 10-6
Convert Handle TM
Handle Receiver 10-6
Convert To Upper
String Giver, subclass of Base String 10-6
Date Setter
Simple Doer, Getter Coordinator 10-4
Simple Doer, Putter Coordinator 10-4
directory figure 10-3
Eject Card
Event Signaller Doer, using ADI2 calls 10-5
list of examples 10-4
Simple Signaller
Simple Signaller Doer 10-4
stages in building the example Worker 10-3
String Searcher
Multi-Thread Doer, Getter Coordinator 10-5
Switcher
Doer and Getter Coordinator 10-5
System Time
String Giver and Receiver 10-4
Trace
Simple Doer, Attribute 10-4
exporting from the Runtime
example code 7-24

APTRA Advance ADE, Programmer’s Guide Index-27


Index

external data types


processing 8-36
production 8-30
Getter 8-26
Getter Coordinator 8-47
header file 7-23
Icon 7-14
Loner 7-16
Message Types 7-5
notebook 7-5
private declarations 7-24
Putter 8-32
Putter Coordinator 8-49
runtime file locations 9-5
directory figure 9-6
Sequencer 7-17
Signal 7-23
Signal Types 7-15
Superclasses 7-6
troubleshooting 9-13
Worker Factory 9-8
build errors C-1
building the factory 9-7
Worker hierarchy 6-2
WorkerMsg
data type
use in the mDoer thread member function 8-24

Index-28 APTRA Advance ADE, Programmer’s Guide


User Feedback Form

Title: APTRA Advance ADE, Programmer’s Guide

Number: B006-6042-B000 Date: March 2003


Cut

NCR welcomes your feedback on this publication. Your comments can be of great value in
helping us improve our information products.

You may send your comments to us electronically. See over for details.

Circle the numbers below that best represent your opinion of this publication.

Ease of use 5 4 3 2 1 0 5 = Excellent


Accuracy 5 4 3 2 1 0 4 = Good
Clarity 5 4 3 2 1 0 3 = Adequate
Completeness 5 4 3 2 1 0 2 = Fair
Organization 5 4 3 2 1 0 1 = Poor
Appearance 5 4 3 2 1 0 0 = Not Applicable
Examples 5 4 3 2 1 0
Illustrations 5 4 3 2 1 0
Job performance 5 4 3 2 1 0
Question resolution 5 4 3 2 1 0
Overall satisfaction 5 4 3 2 1 0

Indicate the ways you feel we could improve this publication.

❑ Improve the table of contents ❑ Add more/better quick reference aids


❑ Improve the overview/introduction ❑ Add more examples
❑ Improve the organization ❑ Add more illustrations
❑ Improve the index ❑ Add more step-by-step procedures
❑ Make it less technical ❑ Add more troubleshooting information
❑ Make it more concise/brief ❑ Add more detail
Write any additional comments you may have below and on additional sheets, if necessary.
Include page numbers where applicable.

Fold
Use the following address to send your comments to us electronically:
e-mail - user.feedback@scotland.ncr.com

Cut
If we may contact you concerning your comments, please fill in the information below:

Name
Organisation:
Company:
Address:

Phone: Fax:

Thank you for your evaluation of this publication. Fold the form where indicated, tape
(please do not staple), affix stamp and drop in the mail.
F8763-0695
Fold

Affix
Postage
Stamp
Here

NCR Financial Solutions Group Ltd.


Information Solutions Feedback
Kingsway West
Dundee
Scotland
DD2 3XX

You might also like