Visible to Intel only — GUID: GUID-C30E4305-986E-4ECB-A51A-0CD3EFB6F38A
Visible to Intel only — GUID: GUID-C30E4305-986E-4ECB-A51A-0CD3EFB6F38A
Create the Fortran COM Server
This topic only applies to Windows.
This topic shows how to create a project, specify the COM server characteristics, generate code for, and implement a sample Fortran COM server project called Adder.
The first step in creating a Fortran COM Server is to create a new project.
Create a Fortran COM Server Project using the Visual Studio* IDE
Start the Visual Studio IDE. Choose File > New > Project.
In the New Project dialog box:
Set Language to Fortran.
Set Platform to Windows.
Set Project Type to COM.
To create the sample project, select project template In-process Server (DLL) and click Next.
Now do the following:
Enter Adder as the name of the project.
Accept or modify the project folder location.
Click Create.
You can use the project AppWizard once per project to create the project files and skeleton template. The Fortran COM Server AppWizard displays default text for the interface name and class derived type name.
Now do the following:
Enter class name AddingMachine.
Shorten the default interface name to IAdd.
Accept the default class derived type name.
Click Finish.
Note that if you click Cancel, project creation is terminated.
The project is created and the COM Server Hierarchy file (adder.hie) is opened in the COM Hierarchy Editor.
Use the COM Hierarchy Editor to Define your COM Server
The COM Hierarchy Editor lets you interactively define the attributes (for example, classes, interfaces, and methods) for your COM server. The user interface contains two panes:
The top pane is a tree control that displays attribute information in a hierarchy.
The bottom pane is a panel that displays the IDL definition for a selected element in the hierarchy.
You can use "right-click" context menus to insert, delete, and modify items in the hierarchy. Context menus also let you change item properties. For example, you can right-click the IAdd element and select Properties to see the IAdd interface properties. You could then change the Is Dual property value to False; this value indicates that the Adder example only supports a COM server interface.
An explanation of the hierarchy follows:
The root is the COM server itself.
The immediate children of the COM server are classes. The hierarchy initially contains a single class, AddingMachine. You can add additional classes to the COM server.
The immediate children of a class are interfaces and the class derived-type. In the example, the hierarchy contains the interface IAdd and the class derived-type AddingMachine_InstanceData. Each class contains one, and only one, class derived-type. You can add additional interfaces to the class.
The immediate children of an interface are methods (one or more).
The immediate children of a method are the method arguments (one or more).
To add a class, interface, method, property, or argument:
Select the parent item, right-click and select the appropriate Add... item.
To delete an item:
Select the item to be deleted, right-click and select Delete.
Click the Delete button.
Continuing with the Adder COM server example, add methods to the IAdd interface:
Right-click the IAdd interface and select Add Method.
Enter Clear as the name of the method.
Repeat steps 1 and 2, this time entering the name of Add.
The Add method requires an argument. To add the Operand argument named Operand:
Right-click on the Add method and select Add Argument.
Enter the argument name, Operand.
The default data type of an argument is INTEGER(4).
Proceeding with this example, use the Properties Window to change the Fortran Type property value to REAL(4).
To add a third (and in this example, the last) method:
Right-click on the IAdd interface and select Add Method.
Enter GetValue as the name for the method.
The GetValue method requires an argument, CurrentValue. To add the CurrentValue argument:
Right-click on the GetValue method and select Add Argument.
Enter CurrentValue as the name of the argument.
For the CurrentValue argument:
Set Fortran Type property value to REAL(4).
Set Intent property values to [out,retval].
The server definition is now complete for this example. When you save the file using File > Save adder.hie, the Fortran sources will be regenerated.
For detailed information about the property pages (right pane) for the server, class, interface, method, argument, or instance properties, see Description of Property Pages.
To change the definition of your server, open adder.hie in the Editor.
Work with the Hierarchy Pane
As you have seen in the AddingMachine example, the hierarchy pane represents the definition of your server; that is, the classes, interfaces, methods, and so on. The hierarchy pane's user interface supports the following functionality:
Function |
Description |
---|---|
Expand/contract an area |
Click the plus sign (+) next to an item to display its children and the - to hide the children. |
Add a new entry |
Select the entry that will precede the new entry in the hierarchy, right-click and select one of the New... menu options. |
Delete an entry |
Select the item to be deleted, right-click and select Delete. All of an item's children are deleted when the item is deleted. |
Rename a member |
Select the item to be renamed, right-click and select Rename. |
Change the order of items |
The hierarchy pane supports drag-and-drop to allow you to change the order of items. The order of some of the entries in the hierarchy is very important. In particular:
|
Description of Property Pages
Property pages appear in the Properties Window. Property pages are available for the following:
Server Property |
Description |
---|---|
Type Library GUID |
The unique identifier of the server's type library. In general, use the default value generated by the Fortran COM Server Wizard. |
Type Library Version |
The current version of the Type Library. |
HelpString |
A string used to set the library's help string attribute in the IDL file. |
Class Property |
Description |
---|---|
ProgID |
The version independent program ID (or text alias) for the class. The ProgID can be used in calls such as COMCreateObjectByProgID. |
Version |
The current version of the class. This value is appended to the ProgID to define the version-specific ProgID. |
Short name |
A short name for the class. This value is used in some of the generated file names. |
Description |
A string used as the default value of the class' ProgID keys in the registry. This string is often used by tools that display a list of the objects that are registered on the system, such as the OLE-COM Object Viewer. |
Help String |
A string used to set the class' help string attribute in the IDL file. |
Threading model |
The threading model of the class. The two choices are Apartment and Single. See Threading Models in Advanced COM Server Topics for information about the implications of this choice. |
CLSID |
The unique identifier of the class. In general, use the default value generated by the Wizard. |
Interface Property |
Description |
---|---|
Is Dual |
If true, then the dual interface attribute is set in the IDL file. A dual interface supports both COM and Automation clients. |
Is OleAutomation |
If true, then the interface uses only Automation-compatible data types as described in Fortran COM Server Interface Design Considerations. |
Is Default |
If true, then the default interface attribute is set for this interface in the IDL file. The default attribute represents the default programmability interface of the object, and is intended for use by macro languages. |
Help String |
A string used to set the interface's help string attribute in the IDL file. |
IID |
The unique identifier of the interface. In general, use the default value generated by the Wizard. |
Method Property |
Description |
---|---|
DISPID |
The identifier of the method used by Automation clients. |
Help string |
A string used to set the method's help string attribute in the IDL file. |
Property Method |
If checked, then the method is the get_ or put_ method of a property. |
Argument Property |
Description |
---|---|
Fortran data type |
The Fortran data type of the argument. Select one of the data types from the list, or type in the data type. See Fortran COM Server Interface Design Considerations for a discussion of the implications of your choice. |
IDL type |
The IDL data type. If you select one of the Fortran data types from the predefined list, then this field defaults to the corresponding IDL data type. Select one of the data types from the list, or type in the data type. See Fortran COM Server Interface Design Considerations for a discussion of the implications of your choice. |
Intent |
The INTENT of the argument, which is one of the following:
|
By Reference |
Indicates that an argument is passed by reference rather than by value. Only valid with Intent In. Intent Out and Intent InOut are automatically passed by reference. |
Is Optional |
If true, then the argument is optional. Optional arguments are passed using the Variant data type. |
Dimensions |
Number of array dimensions (0 if the argument is scalar). |
Instance Type Property |
Description |
---|---|
Module name |
The name used for the module defined in the UclassnameTY.f90 file. |
Constructor name |
The name used for the class constructor defined in the UclassnameTY.f90 file. |
Destructor name |
The name used for the class destructor defined in the UclassnameTY.f90 file. |
Modify the Generated Code
When you save the hierarchy file, Fortran sources are generated (or regenerated). Source files are stored as follows:
Source files that you will need to modify are placed in the Source Files folder.
Files that are complete and need no modification are placed in the Do Not Edit folder.
Modify the following files in the Source Files folder:
UAddingMachineTY.f90, which contains a module that defines your class derived-type.
UIAdd.f90, which contains the implementation of the IAdd methods.
The file UAddingMachineTY.f90 contains the code.
The file contains a module named AddingMachine_USE (in the form classname_USE).
There are three places in this module where you may need to add code specific to your class:
The first entry in the module, marked by <BnDEF> and <EnDEF>, is your class derived-type. Initially it contains an "integer dummy" field to allow the module to be compiled without error. If your class has per-object data, remove the integer dummy field line and add your data to the derived-type. For the AddingMachine class, we add the following where the object stores the current value:
real (4) CurrentValue
The module also contains two module procedures, AddingMachine_CONSTRUCTOR and AddingMachine_DESTRUCTOR (referred to as classname_CONSTRUCTOR and classname_DESTRUCTOR below). The former delineated with <BnCON> and <EnCON>; the latter is delineated with <BnDES> and <EnDES>.
The classname_CONSTRUCTOR procedure is called immediately after an instance of the class derived-type is created because of the creation of a new object. This function is where you initialize the fields of the class derived-type, if necessary. The new derived-type is passed as an argument to the function. For the AddingMachine class, initialize the current value to 0 by adding the following statement:
ObjectData%CurrentValue = 0
The classname_DESTRUCTOR procedure is called immediately before an instance of the class derived-type is destroyed because an object is being destroyed. This function is where you release any resources used by the fields of the class derived-type, if necessary. The derived-type is passed as an argument to the function. For the AddingMachine class, there is nothing that needs to be added.
Now modify the other source file called UIAdd.f90. The original file UIAdd.f90 contains the code.
A file by the name Uinterfacename.f90 (for example UIadd.f90) is created for each interface defined by the class. The file contains the methods of the class. Each method is named interfacename_methodname, for example: IAdd_Clear. Each method is a function that is passed to the class derived-type as the first argument. It gives the function access to the per-object data.
Each function returns a 32-bit COM status code called an HRESULT. S_OK is a parameter that defines a success status. For additional information on COM status codes, see Fortran COM Server Interface Design Considerations.
Replace the ! TODO: Add implementation line in each method with the code for the method. For the IAdd interface, the implementation of its three methods is as follows:
For IAdd_Clear: ObjectData%CurrentValue = 0
For IAdd_Add: ObjectData%CurrentValue = ObjectData%CurrentValue + Operand
For IAdd_GetValue: CurrentValue = ObjectData%CurrentValue
Save the file and, from the Build menu, click Build Solution to build the server. The COM server is now complete.
COM Server Projects and the Microsoft* Interface Definition Language (MIDL) Compiler
During the creation of a COM Server project -- either In-process Server (DLL) or Out-of-process Server (EXE), as described in this section -- the application wizard determines whether Visual C++* is installed. If it is installed, the Microsoft* Interface Definition Language (MIDL) compiler uses the Visual C++ preprocessor. This setting is both the default and recommended setting. If Visual C++ is not installed, the application wizard specifies that the MIDL compiler use the Fortran preprocessor for preprocessing MIDL source files.
It does this by setting the Additional Options property of the MIDL command line to include the following:
/cpp_cmdifort /cpp_opt"/nologo /fpp /P /E /Qoption,fpp,/no-fort-cont"
If, later, you install Visual C++ and want to specify that MIDL should use the Visual C++ preprocessor, remove these options from the MIDL compiler Additional Options property.