= External Classes
:table-number: 0
:toc:

TITAN allows the declaration of external classes in TTCN-3 code, incomplete classes which the user can finish implementing, and extend further, in {cpp}.
To help with the implementation, the TTCN-3 compiler can generate external class skeletons with the command line option `-t`.

These skeletons contain the already implemented parts, as well as declarations and empty definitions for the external methods, of all external classes declared in TTCN-3 code. They also contain a constructor and destructor for each external class, even if these were not declared in TTCN-3.

Clarifications about the skeletons and implementation tips:

* One header (`.hh`) and one source file (`.cc`) is generated for each external class. The base names of these files (i.e. their names before the extensions) are equal to the names of their external class in TTCN-3. Please note that the name mapping rules described in <<6-mapping_ttcn3_data_types_to_c++_constructs.adoc#mapping-of-names-and-identifiers, Mapping of Names and Identifiers>> also apply to the file names.
* Both the generated header and source file can be extended with additional members and methods, however these new members and methods will not be visible in TTCN-3.
* The compiler will not regenerate the external class skeletons, if they already exist. Not even if the external class declaration in TTCN-3 changes. The compiler option `-f` (in addition to `-t`) can be used to force the regeneration of external class skeletons, however this will also overwrite any user code added to the previous skeletons.
* The function definitions generated for external methods are empty, aside from the code to reset `out` parameters, if there are any.
* The constructor's regular and external parameter lists in TTCN-3 are generated into one parameter list in {cpp} (with the regular parameters first, followed by the external parameters). The generated constructor's initializer list contains the call to the base constructor and the initialization of constant and template references. The constructor body contains the initializer code of any members with initial values in TTCN-3.
* A minimal implementation of the `log` function is also generated into each external class skeleton. This can be extended to display more information about the object while logging.
* The header file also contains a static inline function called `class_name`, which is used in error messages.
* The generated destructor automatically contains a try-catch block, to ensure that no exceptions are thrown from the destructor. All user code must be written inside the try-catch block.
* For more information about how to handle references of class types see <<6-mapping_ttcn3_data_types_to_c++_constructs.adoc#object-references, Object References>>.

== Example

Example.ttcn:
[source]
----
type external class ExternalClass {
  template integer t := ?;
  var charstring v;
  create(integer x) external (charstring y);
  public function f_ext(in integer x, out octetstring y) return boolean;
  function f_int(inout charstring p) { p := p & v; }  
}
----

ExternalClass.hh:
[source]
----
// This external class skeleton header file was generated by the
// TTCN-3 Compiler of the TTCN-3 Test Executor version 8.2.0
// for ebotbar (ebotbar@ebotbar-VirtualBox) on Thu Jun  9 16:20:55 2022

// Copyright (c) 2000-2025 Ericsson Telecom AB

// You may modify this file. Add your attributes and prototypes of your
// member functions here.

#ifndef ExternalClass_HH
#define ExternalClass_HH

class ExternalClass :  public OBJECT {
public:
static const char* class_name() { return "ExternalClass"; }

protected:
const INTEGER_template& t;
INTEGER_template template_t;

protected:
CHARSTRING v;

public:
virtual BOOLEAN f__ext(const INTEGER& x, OCTETSTRING& y);

protected:
virtual void f__int(CHARSTRING& p);

public:
ExternalClass(const INTEGER& x, const CHARSTRING& y);

public:
virtual ~ExternalClass();

public:
virtual void log() const;
};

#endif
----

ExternalClass.cc:
[source]
----
// This external class skeleton source file was generated by the
// TTCN-3 Compiler of the TTCN-3 Test Executor version 8.2.0
// for ebotbar (ebotbar@ebotbar-VirtualBox) on Thu Jun  9 16:20:55 2022

// Copyright (c) 2000-2025 Ericsson Telecom AB

// You may modify this file. Complete the bodies of empty functions and
// add your member functions here.

#include "Example.hh"

namespace Example {

BOOLEAN ExternalClass::f__ext(const INTEGER& x, OCTETSTRING& y)
{
y.clean_up();

}

void ExternalClass::f__int(CHARSTRING& p)
{
/* Example.ttcn, line 8 */
{
CHARSTRING tmp_0;
tmp_0 = (p + v);
p = tmp_0;
}
}

ExternalClass::ExternalClass(const INTEGER& x, const CHARSTRING& y)
: OBJECT(), t(template_t)
{
/* Example.ttcn, line 4 */
template_t = ANY_VALUE;
}

ExternalClass::~ExternalClass()
{
try {

} catch (...) {
fprintf(stderr, "Unhandled exception or dynamic test case error in the destructor of class `ExternalClass'. Terminating application.\n");
exit(EXIT_FAILURE);
}
}

void ExternalClass::log() const
{
TTCN_Logger::log_event_str("ExternalClass");
}


} /* end of namespace */
----

NOTE: The user is responsible for the handling of all constructor external parameters. External parameter references are not generated into the base constructor call automatically, if the base constructor also had external parameters. External parameter names may clash with that constructor's regular parameter names (since this is allowed by the compiler), and need to be adjusted manually.
