5.3 Functions with Records as Parameters

To provide functions for dialogs including records with an application, the C modules created by DM have to be compiled and linked. These functions may never occur in a function table which is defined in the application, since these functions are linked via the created module. This way of creating is necessary for each dialog module containing definitions for functions. These modules are created by calling the simulaton with the option +writetrampolin:

idm +writetrampolin <outfile> <dialogscript>

This statement creates the modules needed for the call of functions from a dialog script. The indicated dialog script may be a module here. According to the type of functions using such records the relevant header files (C and/or COBOL) are created.

On implementing these functions the created header file has to be linked to the relevant module. This is done by the following statement:

include

If such functions and records are used in an application, these records have to be initialized by calling the function

RecInit<dialog name>

or

RecMInit<module name>

Note

These functions have not to be linked until DM_BindCallbacks has been called!

If such structures are used in Dialog Manager applications, i.e. if the distributed DM is used, the application for which the files are to be created has to be indicated additionally.

The name of the initialization function is then formed from the name of the application.

Consequently

RecMInit<ApplicationName>

has to be called

idm +writetrampolin <contfile> +application <ApplicationName>
  <dialogscript>

Example

From the dialog

dialog RecTest

{

}

function void WriteAddr(record Address input);

function integer ReadAddr(record Address output, integer);

 

record Address

{

  string[25] Name shadows W1.Lname.E.content;

  string[15] FirstName shadows W1.Lfirstname.E.content;

  string[25] City shadows W1.Lcity.E.content;

  string[30] Street shadows W1.Lstreet.E.content;

}

the following include file is created:

#ifndef __INCLUDED_xxx_h_

#define __INCLUDED_xxx_h_

 

#ifdef __cplusplus

    extern "C" {

#endif

 

typedef struct {

    DM_String Name;

    DM_String FirstName;

    DM_String City;

    DM_String Street;

} RecAddress;

 

void DML_default DM_ENTRY WriteAddr __((RecAddress *));

DM_Integer DML_default DM_ENTRY ReadAddr __((RecAddress *, DM_Integer));

DM_Boolean RecInitRecTest __((DM_ID dialog));

 

#ifdef __cplusplus

    }

#endif

 

#endif /* __INCLUDED_xxx_h_ */

5.3.1 Dynamic Binding of Record Functions

Availability

Since IDM version A.06.01.d

Dynamic binding refers to a binding type for application functions that does not require explicitly setting the function pointer of the application functions by means of the functions DM_BindFunctions or DM_BindCallBacks. This includes, for example, connecting functions from dynamic libraries (transport "dynlib") or calling COBOL functions by their names through the “BindThruLoader Functionality”. However, since application functions with record parameters require an additional stub function for marshalling the record structure, no structure has been transferred so far when these record functions were called.

As of IDM version A.06.01.d, the structure of the record parameters for dynamically bound record functions is transferred without a stub function. Such record functions can be used without generating a C or COBOL code. It is however useful to generate the function prototypes as well as the structure definition via +writeheader <basefilename>.

Example

dialog D
record RecAdr {
  string[80] Name := "";
  string[120] Street := "";
  string[40] City := "";
  integer ZIP := 0;
}

application Appl {
  .transport "dynlib";
  .exec "libadr.so";
  .active true;
  function boolean Search(string Pattern, record RecAdr output);
}

application ApplCobol {
  .local true;
  .active true;
  function cobol boolean New(record RecAdr) alias "NEWADR";
}

on dialog start {
  if not Appl.active orelse not ApplCobol.active then
    print "Application(s) not properly connected!";
  elseif not Search("Joe", RecAdr) then
    print "Joe not found, adding him";
    RecAdr.Name := "Joe";
    RecAdr.Street := "765 East Walnut Lane";
    RecAdr.City := "Oak Park";
    RecAdr.ZIP := 48237;
    New(RecAdr);
  else
    print "Joe found, lives in: "+RecAdr.City;
  endif
  exit(();
}

The prototypes can now simply be generated with +writeheader instead of +writeproto, +writefuncmap and +/-writetrampolin:

pidm adr.dlg +application Appl +writeheader adr       // generates adr.h
pidm adr.dlg +application ApplCobol +writeheader adr  // generates adr.cpy

The actual implementation in C and COBOL can now find the function prototypes or record definitions for RecRecAdr in adr.h (C header file) and adr.cpy (COBOL copy file).

5.3.2 Note for Using DM Functions

Within a C function that uses a record as parameter, this DM function must always be called with the option DMF_DontFreeLastStrings, since otherwise strings contained in the record are also released; these strings would no longer be available.

See Also

Chapter “Handling of String Parameters” in manual “C Interface - Functions” and the respective function descriptions.