Click or drag to resize

Linking IVI-COM and IVI-C Methods and Properties

When IVI-COM items, such as methods, properties, parameters, and enums, are added to the driver hierarchy using the IVI-COM Designer, corresponding items are automatically added to the IVI-C hierarchy. For instance, adding an IVI-COM method automatically adds a corresponding IVI-C function. Since IVI-COM and IVI-C represent data types, repeated capabilities, and other driver characteristics differently, Nimbus must perform various transformations when mapping between IVI-COM and IVI-C. In situations where an IVI-COM item cannot or should not be represented in IVI-C, or vice versa, Nimbus provides a means to implement IVI-COM-only and IVI-C-only items. This topic explains important aspects of managing the relationship between the IVI-COM driver and its associated IVI-C wrapper.

Important note Important

This topic only applies to IVI-COM driver projects that have enabled IVI-C wrapper generation on the IVI-C Page of the Driver Settings Editor.

The IVI-C ViSession Parameter

Every IVI-C function accepts a ViSession as its first parameter. The ViSession parameter identifies the instrument I/O session. Nimbus automatically adds a ViSession parameter to every IVI-C function it associates with an IVI-COM method. Inside the implementation of the IVI-C function, the Nimbus-generated code uses the ViSession parameter to locate the correct IVI-COM driver instance to call. The ViSession parameter cannot be deleted from an IVI-C driver function.

IVI-COM and IVI-C Return Types

At the raw IDL level, all IVI-COM methods return an HRESULT. The HRESULT return value is used to indicate various failure and success conditions. However, the Nimbus IVI-COM Method Editor allows a return type to be specified for each IVI-COM driver method. This is because many environments, such as C# and VB.NET, transform an IVI-COM HRESULT into an exception or other error mechanism. This allows an [out] parameter to be designated as the method's return value and simplifies the use of the IVI-COM method.

By contrast, IVI-C functions always return a ViStatus result. This means that if an IVI-COM method specifies anything other than Void as its return type, an [out] parameter of the specified type must be added to the corresponding IVI-C function function signature. Nimbus adds such an [out] parameter automatically when needed.

Mapping IVI-COM and IVI-C Data Types

When an IVI-COM method is associated with an IVI-C function, the method return type as well as the data type of each parameter must be mapped to an appropriate IVI-C data type. Similarly, an IVI-COM property type must be mapped to its corresponding IVI-C attribute type. Nimbus performs these transformations automatically when an IVI-COM method or property is created and when parameters are added. Most of these mappings are straightforward and are given in the table below:

IVI-COM Data Type

IVI-C Data Type

Boolean

ViBoolean

String

ViConstString (for [in] parameters)

ViString, plus a BufferSize parameter (for [out] and [in,out] parameters)

(See discussion below.)

Byte

ViChar

Int16

ViInt16

Int32

ViInt32

Int64

ViInt64

Single

ViReal32

Double

ViReal64

Mapping Array Parameters

IVI-COM drivers use the SAFEARRAY data type for array parameters. One convenient feature of SAFEARRAYs is that they are self-describing -- the number and type of elements present in the array is maintained within the SAFEARRAY itself. IVI-C drivers, however, use C-style arrays. Since C-style arrays are simply pointers, extra parameters must be used with an IVI-C array to indicate the number of elements present. The IVI specifications prescribe specific naming and ordering conventions for these extra "array size" parameters. Nimbus automatically manages these extra IVI-C parameters as follows:

When a SAFERRAY parameter is added to an IVI-COM method or property

  1. An [in] parameter of type ViInt32 is added to the IVI-C function and placed just before the IVI-C array parameter. The parameter name is based upon the array parameter name, as follows:

    <arrayParamName>BufferSize

    This buffer size parameter is used to indicate how many elements (not bytes) have been allocated in the array by the caller. This helps ensure the function implementation does not try to access more elements than are available.

  2. A C-style array is added to the IVI-C function to represent the SAFEARRAY data itself.

  3. If the SAFEARRAY parameter is an [in,out] parameter, then an [out] parameter of type ViInt32 is added to the IVI-C function and placed just after the IVI-C array parameter. The parameter name is based upon the array parameter name, as follows:

    <arrayParamName>ActualSize

    This actual size parameter is used to indicate how many elements (not bytes) were filled in by the function implementation. This indicates to the caller how much of the allocated space, as indicated by the buffer size parameter, was actually used.

Mapping String Parameters

IVI-COM drivers use the BSTR data type for string parameters. Similar to the COM SAFEARRAY data type, the BSTR data type has the convenient feature of managing the string length internally. All BSTRs are length-prefixed, so extra parameters are never needed to indicate the number of characters present. IVI-C drivers, on the other hand, use character arrays (arrays of ViChar typedef'd to the ViString data type). When used as input parameters IVI-C strings do not need additional length parameters because the string is NULL-terminated and the length is easily determined by the function implementation. However, when strings are used as [out] parameters in IVI-C drivers, an additional buffer size parameter must be used to indicate to the function implementation how many characters have been allocated by the caller. The IVI specifications prescribe specific naming and ordering conventions for this extra "buffer size" parameter. Nimbus automatically manages this extra IVI-C parameter as follows:

When a string [out] parameter is added to an IVI-COM method or property

  1. An [in] parameter of type ViInt32 is added to the IVI-C function and placed just before the IVI-C ViString parameter. The parameter name is based upon the ViString parameter name, as follows:

    <stringParamName>BufferSize

    This buffer size parameter is used to indicate how many characters have been allocated in the string by the caller. This helps ensure the function implementation does not try to access more characters than are available.

  2. A ViString parameter is added to the IVI-C function to represent the BSTR data itself.

Mapping IVI-COM and IVI-C Repeated Capabilities

IVI-COM and IVI-C have a few important differences in the way they represent repeated capabilities. The first difference of note is that IVI-C drivers do not support collection-style repeated capabilities. IVI-COM and IVI-C drivers also use a different set of IVI-defined standard methods and properties to manage the repeated capability instances.

The table below presents the required repeated capability methods and properties for IVI-COM and IVI-C drivers based upon the type of repeated capability. For a discussion of the different types of repeated capabilities see the IVI Backgrounder topic on Repeated Capabilities.

Repeated Capability Style

IVI-COM

IVI-C

Collection-Style

  • Count property

  • Item property

  • Name property

  • Not supported.

Parameter-Style

  • <Capability>Count property (Ex: ChannelCount)

  • <Capability>Name property (Ex: ChannelName)

  • <CAPABILITY>_COUNT attribute (Ex: CHANNEL_COUNT)

  • Get<Capability>Name function (Ex: GetChannelName)

Selector-Style

  • <Capability>Count property (Ex: ChannelCount)

  • <Capability>Name property (Ex: ChannelName)

  • Active<Capability> property (Ex: ActiveChannel)

  • SetActive<Capability> method (Ex: SetActiveChannel)

  • <CAPABILITY>_COUNT attribute (Ex: CHANNEL_COUNT)

  • Get<Capability>Name function (Ex: GetChannelName)

  • ACTIVE_<CAPABILITY> attribute (Ex: ACTIVE_CHANNEL)

  • SetActive<Capability> function (Ex: SetActiveChannel)

As the table shows, different methods and properties must be maintained in the IVI-COM and IVI-C hierarchies based upon the type of repeated capability. Nimbus automatically handles each case by creating the appropriate IVI-C functions and attributes and associating them with their IVI-COM counterparts.

Collection-Style Repeated Capabilities and IVI-C

The case of collection-style repeated capabilities requires special handling since this type of repeated capability is not supported by IVI-C drivers. Whenever a collection-style repeated capability is added to a driver, Nimbus treats the repeated capability as a parameter-style repeated capability in the IVI-C hierarchy. This means Nimbus automatically creates the <CAPABILITY>_COUNT attribute and the Get<Capability>Name function and associates them with the IVI-COM Count and Name properties.

Important note Important

Collection-style repeated capabilities in an IVI-COM driver are always treated as parameter-style repeated capabilities in the IVI-C hierarchy.

Creating IVI-C Getter and Setter Functions

Reading and writing IVI-C attributes involves use of special attribute accessor functions that accept a #define'd constant representing the attribute ID and a value parameter. Because this programming model can be a bit cumbersome to work with in practice, the IVI specifications recommend that commonly used IVI-C attributes also expose a corresponding "getter" and "setter" function. By convention, setter functions often have names that begin with "Configure" and getter functions have names that begin with "Query" (although there is no hard requirement to follow these naming conventions).

Using an IVI-C setter or getter function in place of the attribute itself can simplify programming with the IVI-C driver, as shown in the simple example below:

C++
ViSession vi;
/* session initialization omitted for clarity */

/* Use the attribute and attribute accessor to set the sample rate to 1000 */
ViStatus status = IviScope_SetAttributeViReal64(vi, VI_NULL, IVISCOPE_ATTR_HORZ_SAMPLE_RATE, 1000);

/* Use the setter function to set the sample rate to 1000 */
status = IviScope_ConfigureSampleRate(vi, 1000);

Nimbus provides built-in support for the creation of IVI-C getter and setter functions and it maintains an association between these functions and the attribute so that they can be automatically implemented by Nimbus.

To create an IVI-C getter or setter function

  1. From Solution Explorer, double-click the IVI-COM node to bring up the IVI-COM Designer.

  2. Select a property from the IVI-COM hierarchy.

  3. Right-click on the property and choose Create IVI-C Getter Function or Create IVI-C Setter Function.

    Note Note

    The Create IVI-C Getter Function command will not be available if the property is write-only. Similarly, the Create IVI-C Setter Function command will not appear if the property is read-only. Also, if the getter or setter function already exists, then the corresponding context menu command will not be available.

Parameterized Properties and IVI-C Getters and Setters

A property that accepts parameters is known as a parameterized property. While IVI-COM drivers naturally support parameterized properties, there is no notion of a corresponding "parameterized attribute" in IVI-C. Thus, whenever a parameter is first added to an IVI-COM property, Nimbus automatically performs the following steps:

  1. If the IVI-COM property has an associated IVI-C attribute, the IVI-C attribute is deleted from the IVI-C hierarchy.

  2. If the IVI-COM property is read-write or read-only, an IVI-C getter function will be created and associated with the property. The getter function will be named as follows:

    Get<propertyName>

  3. If the IVI-COM property is read-write or write-only, an IVI-C setter function will be created and associated with the property. The setter function will be named as follows:

    Set<propertyName>

Creating IVI-COM-only and IVI-C Methods and Properties

There are some instances where it is not possible or desirable to expose an IVI-COM method in the IVI-C driver. Such an IVI-COM method has no associated IVI-C function and is termed an IVI-COM-only method. Correspondingly, there are occaisions where an IVI-C function serves no useful purpose in the IVI-COM hierarchy. This requires IVI-C functions that have no IVI-COM counterpart -- these are termed IVI-C-only functions.

IVI-COM-only methods and properties are established by deleting the associated IVI-C function or attribute.

To create an IVI-COM-only method or property

  1. From the IVI-COM Designer, select the desired method or property.

  2. For a method, right-click and choose Delete IVI-C Function.

    For a property, right-click and choose Delete IVI-C Attribute. If the property also has a getter and/or setter associated with it, then you can select Delete IVI-C Getter Function and/or Delete IVI-C Setter Function to remove those as well.

  3. The Info Panel should display None for the associated IVI-C items.

IVI-C-only functions and attributes are created by simply adding an IVI-C function or attribute directly using the IVI-C Designer. Recall that the IVI-C Designer does not push changes to the IVI-COM hierarchy, so anything created directly from the IVI-C Designer is inherently IVI-C-only.

Important note Important

Whenever an IVI-C-only function or attribute is created, it must be manually implemented in the <prefix>.cpp file within the driver project. See the topic Implementing IVI-C-Only Functions and Attributes for more information.

To create an IVI-C-only function or attribute

  1. From the IVI-C Designer, select the desired location within the IVI-C tree view.

  2. Right-click and choose Add Function or Add Attribute.

  3. The Info Panel shows that no IVI-COM method or property is associated with the item.

See Also

Download a complete CHM version of this documentation here.