Intel® Fortran Compiler Classic and Intel® Fortran Compiler Developer Guide and Reference

ID 767251
Date 7/13/2023
Public

A newer version of this document is available. Customers should click here to go to the newest version.

Document Table of Contents

Fortran COM Server Interface Design Considerations

This topic only applies to Windows.

This topic provides information that should be considered when designing a Fortran COM server. It contains the following topics:

Method and Property Data Types

COM places some restrictions on the data types used in COM methods and properties. The reason for the restrictions is that COM can pass arguments between threads, processes and machines. This behavior raises issues that are not present in older technologies, such as DLLs, that always run in the same address space as the caller.

COM defines set of data types called Automation-compatible data types. Automation-compatible data types are the only data types that can be used in Automation and Dual interfaces. The following are two advantages to restricting your COM interface to these data types:

  • Your server will be usable from clients written in the largest set of languages, including Intel® Fortran, Visual Basic, and Visual C++.

  • COM will automatically handle the passing of arguments between threads, processes and machines. This is called Type Library Marshalling. For more information, see Marshalling, Proxies and Stubs in Advanced COM Server Topics.

To restrict your server to Automation-compatible data types:

  1. Select Use only Automation data types on the Interface property page. When defining a dual interface, this selection is automatically set.

  2. Use only the following combinations of Fortran data type and Interface data type on the Argument property page.

    Note that Intel Fortran does not support the Currency, Decimal, or User Defined Type, Automation-compatible data types.

Fortran Date Type

Interface Data Type

INTEGER(1)

unsigned char

INTEGER(2)

short

INTEGER(4)

long

SCODE

Int

INTEGER(INT_PTR_KIND())

IUnknown*

IDispatch*

REAL(4)

float

REAL(8)

double

DATE

LOGICAL(2)

VARIANT_BOOL

LOGICAL(4)

long

CHARACTER(1)

unsigned char

CHARACTER(*)

BSTR

BYTE

unsigned char

TYPE(VARIANT)

VARIANT (containing one of the above types or SafeArray)

If you decide not to restrict your interface to Automation-compatible data types, the next approach is to restrict your interface to data types that can be described in the Interface Description Language (IDL).

The Fortran COM Server Application Wizard automatically generates the IDL file from the description of your server. The Microsoft Interface Definition Language (MIDL) compiler compiles the IDL file into a type library. MIDL can also automatically generate the code needed handle the passing of arguments between threads, processes and machines. Note, however, that a C compiler is required to use this option. For more information, see Discussion of Wizard Code Generation in Advanced COM Server Topics.

If you decide not to restrict your interface to IDL data types, your only remaining options are as follows:

  • Implement Custom Marshalling

    For more information, see Marshalling, Proxies and Stubs in Advanced COM Server Topics.

  • Decide that you will never use your server across apartment, thread, or process boundaries. The server will not be usable in this manner because there is no way to pass the arguments across these boundaries.

COM Status Codes: HRESULT

Each function returns a 32-bit COM status code called an HRESULT. An HRESULT is divided into fields:

  • The top bit (31) indicates whether the function succeeded or failed. The bit is set if the function failed. In Fortran, you can compare the HRESULT to < 0 as a test to see if a function failed.

  • Bits 16 to 27 contain a facility code to indicate the facility that issued the HRESULT. Microsoft predefines a number of facility codes for its own use. If you create your own status codes, use FACILITY_ITF. All other facility codes are reserved by Microsoft.

  • The first 16 bits, or low word, contain the error code specific to the error that occurred.

A typical HRESULT error value could be a value such as 0x80070057. The first hex digit, 8, indicates that bit 31 is set and that this value is an error value. Bits 16 to 27 contain the value 7. This value indicates the facility FACILITY_WIN32. The low word contains the value 0057. This value is the specific code that identifies the error as E_INVALIDARG.

To view the text description that corresponds to a system HRESULT value, use the Error Lookup tool in the Intel® Fortran program folder. For example, entering the value 0x80070057 retrieves the text message "The parameter is incorrect.".

You can also search for HRESULT values in the WINERROR.H file in the \VC\INCLUDE directory.

Visual Basic*, Visual C++*, and Intel® C++ Client Notes

To use an object from Visual Basic, you must add a reference to the object to the Visual Basic project. Use the References item in the Project menu to display a list of the registered objects. Select the object in the list to inform Visual Basic that you will be using the object.

Here are some rules to be aware of when writing a server that can be used with Visual Basic clients:

  • Use only the Automation-compatible data types (see Method and Property Data Types).

  • Arguments to a method can be passed ByVal, ByRef, or they can be the function return value.

  • An argument to be passed ByVal, must be defined with Intent set to In.

  • An argument to be passed ByRef, must be defined with Intent set to InOut.

  • A function return value must be defined with Intent set to Out. It must have the Return Value field checked. The argument must be the final argument of the method.

  • An array is always passed as a SafeArray ByRef. Therefore it must be defined with Intent set to InOut.

  • To use an argument of the Visual Basic Boolean data type, set the Fortran data type to LOGICAL(2) and set the Interface data type to VARIANT_BOOL.

To use an object from C++, use the #import directive. The syntax of the #import directive is:

  #import "filename" [attributes]
  #import <filename> [attributes]

The file name is the name of the file containing the type library information. The directive makes the information in the type library available to your source file as a set of C++ classes.