Home  /  Application Development: Language Bindings and Gateways  /  Using C++ with InterSystems IRIS  /  Generating Proxy Classes

Using C++ with InterSystems IRIS
Generating Proxy Classes
[Back]  [Next] 
InterSystems: The power behind what matters   

Proxy classes are generated by the InterSystems IRIS™ C++ Class Generator (see Using the C++ Generator), which reads the definition of an InterSystems IRIS class and uses the information to generate a corresponding C++ class. The generated class provides remote access to an instance of an InterSystems IRIS object from within a C++ application.
The C++ Generator produces C++ proxy classes that have the same inheritance hierarchy as the corresponding InterSystems IRIS classes. The type of a class (such as persistent or serial) determines its corresponding C++ superclass. For example, persistent classes have corresponding C++ classes derived from the C++ Persistent_t class included in the InterSystems IRIS C++ library. In case of multiple inheritance, a class becomes a subclass of the first superclass in InterSystems IRIS, and all methods and properties from other direct superclasses are generated as members of the proxy class.
The InterSystems IRIS C++ class library includes C++ versions of a number of the classes within the InterSystems IRIS class library, including %Persistent, %RegisteredObject, %SerialObject, the various InterSystems IRIS collection classes, and C++ versions of the various data type classes. In addition, the library contains the various classes used within a C++ application to manage the communication with the InterSystems IRIS server.
The C++ binding doesn't check at runtime to see whether metadata has changed since code was generated. In particular, it doesn't check whether the application is connecting to the same namespace as at code generation time, and doesn't check whether the classes are defined in the runtime namespace. If they aren't, it will go ahead and insert data anyway, but this data won't be accessible via SQL or via the object interface.
Standard Proxy Class Methods
In addition to any methods defined by an InterSystems IRIS class, all C++ proxy classes inherit a set of methods from the standard InterSystems IRIS C++ library classes Persistent_t (for persistent classes) or Registered_t (for serial classes).
The C++ Generator also adds a set of static create and open methods to the generated classes. To protect the C++ classes from incorrect usage, the proxy class constructors are made private. The only way to instantiate a generated class T is to call one of the static methods T::create_new(), T::open(), or T::openid(), each of which returns a d_ref<T> object (see Using Proxy Objects). These methods are generated only if the corresponding InterSystems IRIS methods exist for a given class.
The static methods are defined as follows (where My_Class is the name of the proxy class):
Implementing Proxy Methods
C++ instance methods are generated for InterSystems IRIS instance methods and C++ static methods are generated for InterSystems IRIS class methods. When called on the client, a C++ method invokes the actual method implementation on the InterSystems IRIS server. If a method signature includes arguments with default values, InterSystems IRIS uses the same default values within the generated C++ method. For example, suppose you define a simple InterSystems IRIS class with one method:
   Class MyApp.Simple Extends %RegisteredObject {
      Method LookupName(id As %String) As %String {
         // lookup a name using embedded SQL
         Set name = ""
         &sql(SELECT Name INTO :name FROM Person WHERE ID = :id)
         Quit name
The resulting C++ class header would look similar to the following:
   class MyApp_Simple : public Persistent_t {
      friend d_ref<MyApp_Simple>;
      // code
      virtual d_string LookupName(d_string id);
When a method is invoked from C++, the C++ client first synchronizes the server object cache, then invokes the method on the InterSystems IRIS server, and finally, returns the resulting value (if any). If any method arguments are specified as call-by-reference then their value is updated as well.
Implementing Proxy Properties
Properties in C++ proxy classes are accessed through a pair of accessor methods. Each property has a corresponding get<Property>() method to get its value and a set<Property>() method to set its value.
The values for literal properties (such as strings or integers) are represented using the appropriate C++ data type classes provided with the InterSystems IRIS C++ class library (such as d_string or d_int).
The values for object-valued properties are represented using the d_ref template class (see Using Proxy Objects).
For example, suppose you have defined a persistent class within InterSystems IRIS containing two properties, one literal and the other object-valued:
   Class MyApp.Student Extends %Persistent {
      // Student's name
      Property Name As %String;
      // Reference to a school object
      Property School As School;
The C++ representation of MyApp.Student contains get and set accessor methods for both the Name and School properties. In addition, it provides accessors for the object Id for the referenced School object.
For example, in the sample class, Sample.Person, the DOB property is defined as follows:
   Property DOB As %Date(POPSPEC = "Date()");
The POPSPEC content is for populating the class with sample data and would not appear in an actual application. The C++ accessor methods for Sample.Person are:
   virtual d_date getDOB() const;
   virtual void setDOB(const d_date&);
When a C++ object is instantiated within C++, it fetches a copy of its property values from the InterSystems IRIS server and copies them into a local client-side cache. Subsequent access to the object's property values are made against this cache, reducing the number of messages sent to and from the server. InterSystems IRIS automatically manages this local cache and ensures that it is synchronized with the corresponding object state on the InterSystems IRIS server.
Property values for which you have defined a Get or Set method within your InterSystems IRIS class definition (to create a property whose value depends on other properties for example) are not stored within the local cache. Instead when you access such properties the corresponding accessor method is invoked on the InterSystems IRIS server. As this can entail higher network traffic, you should exercise care when using such properties within a client/server environment.
Naming Conventions
A generated C++ identifier, such as the name of a class, method, or variable, is usually the same as that of the corresponding InterSystems IRIS identifier. This section describes the exceptions to that rule.
It is important to remember that, unlike ObjectScript, C++ identifiers must contain only characters A-Z, a-z, 1–9, and "_" (underscore). If an InterSystems IRIS identifier contains characters that are not permitted in C++, those characters will be replaced by underscores. If the InterSystems IRIS identifier consists of high-order Unicode characters, this may result in a C++ identifier that contains nothing but underscores. Alternate class and package names can be defined in InterSystems IRIS, as described below.
For details on ObjectScript naming conventions, see Variables in Using ObjectScript, Naming Conventions in Defining and Using Classes, and Rules and Guidelines for Identifiers in the Orientation Guide for Server-Side Programming.
Using the C++ Generator
The InterSystems IRIS C++ Generator is a program that generates a C++ class and header file from an InterSystems IRIS class definition. It is available either as a command line program, or as an option in Studio. If InterSystems IRIS is installed with level 3 ("locked down") security, %Service_Bindings must be enabled in order to run the Generator.
To access the Generator from Studio, select Tools > Generate C++ projection from the main menu. This option does not allow you to generate projections for the Light C++ Binding, which must use the command line program with the -lc parameter.
The command line program, cpp_generator.exe, is installed in the <install-dir>\dev\cpp\lib directory, which must be in your Path. (See Default Installation Directory in the Installation Guide for the location of <install-dir> on your system).
The syntax for the program is:
   -conn <conn>
   -user <user>
   -pswd <password>
   -path <path>
   [-class <class>] | [-class-list <filename>]
For example:
   -conn "localhost[1972]:SAMPLES"
   -user "MyUserName"
   -pswd "MyPassword"
   -path "./cppfiles"
   -class "Sample.Person"
C++ Generator Parameters
A connection string with the format <host>[<port>]:<namespace>.
For example:
-conn "localhost[1972]:SAMPLES"
A string specifying the username.
A string specifying the password.
Either a classname or the name of a file containing a list of classnames.
The -class <class> option specifies an InterSystems IRIS server classname. For example:
The -class-list <filename> option specifies the name of a file containing InterSystems IRIS server class name strings (and nothing else), one per line. For example:
where classlist.txt contains the following lines:
A string specifying the directory in which the generated C++ class is to be placed.
-lc Optional. If the -lc switch is used, the generator will produce Light C++ Binding classes.
-help Optional. Displays the list of C++ Generator parameters.
The C++ Generator will automatically generate code for any other classes required to implement the specified class. For example, if you specify -class "Sample.Employee", code will also be generated for the Sample.Person and Sample.Address classes, because Sample.Employee is derived from Sample.Person, and Sample.Person has properties of type Sample.Address.