Integrations (PTC products, 3rd party products and code) > Code integration (Ada, ARINC 653, C, C#, C++, IDL, Java, SQL and VB) > C Code > Generating C Code > Overview of generating C code (C code) > Overview of modeling C code (C code) > Overview of modeling C code (C code) > Class mapping for C (C code)
  
Class mapping for C (C code)
For each Class that is not nested, ACS generates a header file (.h) and an implementation file (.c). Each Class maps to a struct in the header file created for the Class, unless the Class is stereotyped by the «C Module» stereotype.
Example code:
// foo.h
struct foo
{
};
ACS ignores Classes that are stereotyped by the «requirement» stereotype, which is available in the SysML Requirements profile.
Classes that Implement Interfaces
For Classes that implement interfaces:
The first member of the generated struct is named 'base' and is typed by the implementing interface.
ACS generates a 'constructor' function, assigns appropriate functions to the function pointer members of the 'base' member, and assigns values to behavior ports.
The Class provides proxies for functions being forwarded to behavior ports that cast the instance parameter to the correct concrete type before making a call.
For Classes containing composite interface-typed non-behavior ports, ACS generates constructor functions that assign functions to the port's function pointer members.
The struct declaration and implementation is derived from the items it owns, properties of the Class, the application of the «C Module» stereotype, and the tagged values set for Tag Definitions applied by the «C Class» stereotype.
Child items:
If the Class owns Attributes, the Attributes are generated within the struct declaration. For Attribute mapping information, see Attribute mapping for C (C code)
Example code:
struct foo
{
int anAttribute;
};
If a typed Part (Attribute) has an Association that has not been rolled up to the Part's type, ACS generates a nested struct that is derived from the Part's type. The nested struct defines the Role that is modeled against the Part.
If a Class owns Parts (Attributes or Roles) that are connected through an Association, initialization code is generated in the constructor for the class.
Reverser Notes: When reverse engineering a struct's attributes, the Reverser will reverse engineer an attribute as a Role if all of the following statements are true:
The C attribute's data type can be identified as a struct in the code being reverse engineered.
The C struct that is used as a data type is being reverse engineered.
The Reverser cannot match the C attribute to an Attribute in the Model.
For Attributes that are set up as ports, see the preceding Classes that Implement Interfaces section.
If the Class owns Classes, the nested Classes are generated within the struct declaration, unless its C Non Member tag definition is set to TRUE.
Example code:
struct foo
{
struct nested1 //C Non Member = False
{
};
};
struct nested2 //C Non Member = True
{
};
Reverser Notes: When reverse engineering a file, the struct whose name matches the file name is reversed engineered as the root Class, with all other file structs reverse engineered as nested Classes. If a file struct is not nested in the root struct, its reverse engineered Class has its C Non Member tag definition set to TRUE however, if the name of the code file matches the name of the owning folder, the content of the code file is reverse engineered as items scoped to the Package that is created for the folder.
If the Class owns Data Types, the nested Data Types are generated within the struct declaration, unless its C Non Member tag definition is set to TRUE.
If the Class owns Dependencies, ACS typically generates #includes in the code. For Dependency mapping information, see Dependency mapping for C (C code)
Example code:
#include "foo.h"
If the Class owns Generalizations that define inheritance, the attributes are rolled down. Rolled down attributes are indicated through comments. For Generalization mapping information, see Generalization mapping for C (C code)
Example code:
struct Class3
{
/* Start of RtS Rolled Down Items */
int Attribute1;
int Attribute2;
/* End of RtS Rolled Down Items */
int Attribute3;
}
If the Class owns Interfaces, the nested Interfaces are generated within the struct declaration, unless its C Non Member tag definition is set to TRUE.
If the Class owns Operations, the Operations are generated in the file created for the owning Class, but outside of the struct definition. For Operation mapping information, see Operation mapping for C (C code)
Example code:
struct foo
{
};
int anOperation();
If the Class owns Roles, the Roles are typically generated as attributes within the struct declaration. For Role mapping information, see Association and role mapping for C (C code).
Example code:
struct foo
{
AnotherClass rAnotherClass;
};
If a typed Part (Role) has an Association that has not been rolled up to the Part's type, ACS generates a nested struct that is derived from the Part's type. The nested struct defines the Role that is modeled against the Part.
If a Class owns Parts (Attributes or Roles) that are connected through an Association, initialization code is generated in the constructor for the Class.
For Roles that are set up as ports, see the preceding Classes that Implement Interfaces section.
If the Class owns Type Definitions, the Type Definitions are generated in the file created for the owning Class, but outside of the struct definition. For Type Definition mapping information, see Type definition mapping for C (C code).
Example code:
struct foo
{
};
typedef char* StringPtr;
Properties:
The Abstract property is ignored.
If the Description property has a value, ACS generates the description as a comment on the line before the struct declaration.
Example code:
/* Comment for class foo */
struct foo
{
};
The Formal Template Parameters property is ignored.
The Name property is generated as the name of the header and implementation files, and the name of the struct in the code.
Example code:
typedef struct
{
int a;
} bar;
* 
ACS may modify the struct name that is added to the code to make it valid for C. You can specify the exact struct name to add to the code through the CODE_GENERATION_NAME property of a Class. Tell me more...
The Persistent property is ignored.
The Template property is ignored.
The TemplateSpecializationParameters property is ignored.
The TemplateSpecialization property is ignored.
If the Union property is set to TRUE (Union check box selected in Property Pages), the Class is generated as a union.
Example code:
union foo
{
};
If the Visibility property is set to Public or Protected, the struct is declared in the header file. If the Visibility property is set to Private, the struct is declared in the implementation file. For nested Classes, this property is ignored.
Tag Definitions:
If the «C Module» stereotype is applied to a Class, ACS generates a header and implementation file for the Class, but it does not generate a struct for the Class. For nested Classes, this stereotype is ignored.
The following tag definition is applied to a Class by the «C Class» stereotype:
If the tagged value of the C Anonymous Itemtag definition is set to TRUE, it means that the struct is used as an anonymous type and is generated inline.
Example code:
// A typedef called PersonDetails whose underlying type is an anonymous struct.
// The struct would get reversed as something like unnamed0. We would never generate
// the struct on its own, only as part of another declaration.
typedef struct
{
int age;
char* name;
} PersonDetails;
Reverser Notes: When reverse engineering a struct that is used as an anonymous type, the Reverser creates a Class in Modeler and sets its C Anonymous Item tag definition to TRUE. The name of the Class is as follows:
unnamed<integer to make unique>
If the tagged value of the C Forward Declarations tag definition references any Classes, Data Types, Interfaces and Type Definitions, ACS generates forward declarations to the structs, unions and enums that are generated from those items.
Example code:
#ifndef __Class1
#define __Class1
struct Class2;
struct Class1
{
int age;
};
Reverser Notes: When reverse engineering a class that has forward declarations, the C Forward Declaration tag definition references those Classes, Data Types, Interfaces and Type Definitions if they are modeled in the Model, else the forward declarations are recorded as text through the C Forward Declarations Text tag definition
If the tagged value of the C Forward Declaration Text tag definition has been set, the value is generated as forward declarations.
Example code:
#ifndef __Class1
#define __Class1
struct Class2;
struct Class1
{
int age;
};
Reverser Notes: When reverse engineering forward declarations, the C Forward Declaration tag definition references those Classes if they are modeled in the Model, else the forward declarations are recorded as text through the C Forward Declarations Text tag definition.
If the tagged value of the C Header File tag definition has been set, the value is used to generate #include statements. This value is set by ACS and is used when opening an associated header file from Modeler.
If the tagged value of the C Header File Comment tag definition has been set, the value is generated as a header file comment.
Example code:
/* This is the header file comment
For file foo.h*/
/* Class foo */
struct foo
{
};
If the tagged value of the C Header Includetag definition has been set, the value is generated at the beginning of the header file so that you can generate your own #includes to files that are not modeled in the Model. Note that you can use Dependencies to generate #includes to other Classes, Data Types and Interfaces that are modeled in the Model.
Example code:
/* File foo.h */
#include "bar.h"
#include "fred.h"
If the tagged value of the C Implementation File Comment tag definition has been set, the value is generated as an implementation file comment. .
Example code:
/* This is the implementation file comment
For file foo.c*/
/* op bar */
void bar()
{
}
If the tagged value of the C Implementation Include tag definition has been set, the value is generated at the beginning of the implementation file so that you can generate your own #includes to files that are not modeled in the Model. Note that you can use Dependencies to generate #includes to other Classes that are modeled in the Model.
Example code:
/* File foo.c */
#include "bar.h"
#include "fred.h"
If the tagged value of the C Non Member tag definition is set to TRUE (applies only to nested Classes), ACS generates the struct in the code file created for the root Class, but not as part of the struct created for the root Class.
Example code:
struct Class1
{
struct NestedClass1
{
int Attribute1; // C Non Member = FALSE
};
int Attribute1;
};
struct NestedClass2 // C Non Member = TRUE
{
int Attribute2;
};
If the tagged value of the C Source File tag definition has been set, the value is used when opening an associated implementation file from Modeler. This value is set by ACS.
If the tagged value of the C Generate State Machine tag definition has been set to FALSE, ACS does not generate state machine code for the Class' State Diagram
The following tag definition is applied to a Class by the «C Library» stereotype:
If a value has been set for the tagged value of the C LIB_INCLUDE tag definition, the value is generated as the #include for any structs that use the library, rather than ACS generating a #include based on the library's location in the model.