All SAS IOM interfaces are designed
to work well with Microsoft Visual C++.
The documentation is
written in terms of Visual Basic. This means that the default interface
of a component is listed as if it were the interface of the COM object
(coclass) itself, even though in pure COM terms, the default interface
is just one of many interfaces implemented by the object. Thus, a
C++ programmer programs to the IWorkspace interface, even though the
Visual Basic documentation shows the methods as belonging to the Workspace
object. This section discusses issues with which Visual C++ programmers
must be concerned (in addition to the material covered in
Programming with Visual Basic ).
All IOM interfaces implemented
by SAS are COM dual interfaces. Therefore, methods and property get
and set routines can be called as direction entry points with positional
parameters. Although IOM interfaces implement an IDispatch interface
at the beginning of each v-table, this is only for compatibility with
older OLE Automation controllers. Visual C++ programs should not make
calls by using IDispatch::Invoke; but should instead call through
the v-table entry for the specific method that they want to call.
The ClassWizard-generated wrappers for IDispatch (with COleDispatchDriver)
should not be used in IOM programming. This feature of Visual C++
is now useful only for interfaces that contain only IDispatch.
All event (also called
source) IOM interfaces are COM custom interfaces. This means that
callers to the Advise method should pass interfaces that derive only
from IUnknown, not IDispatch. All parameters to the event interfaces
are only in parameters, which means that none of the interfaces support
the ability to return data to SAS through the event interface.
To use the IOM interface
in your Visual C++ program, you should import the IOM interface type
library. Here is an example:
In order for this to
work, you must ensure that the type library directory is listed in
your include path.
The import statement
causes everything in the type library to be placed in a namespace.
The fully qualified name for IWorkspace is SAS::IWorkspace. Also see
the Using directive in Visual C++, and the
-no_namespace
attribute on the import statement.
When you import a type
library, the Visual C++ compiler creates a comprehensive set of definitions
that are specific to that type library by using the helper classes
in COM compiler support (as defined through <comdef.h>). The
helper classes perform many useful functions, including the following:
-
provide smart pointers for interface
references
-
map COM HRESULTs to C++ exceptions
-
use helper classes for BSTRs
-
create wrapper functions that return
the IDL-defined return value instead of an HRESULT
-
provide create instance helpers
Programming with the
Visual C++ COM compiler support is almost as easy as calling the functions
in Visual Basic.
Unfortunately, as of
Visual C++ version 6, the COM compiler support is lacking in one important
area. There are no wrapper functions for handling safe arrays. You
must deal with the OLE Automation safe array API directly.
Dealing with dimensions
in this API requires care. You must be particularly careful if you
are dealing with two-dimensional arrays. The APIs that deal with safe
arrays take a dimension number that is 1-based. In a two-dimensional
array, the rows are indexed in dimension 1 and the columns by dimension
2. When you create an input array by using SafeArrayCreate(), the
bounds are also passed in this order (the row bounds are passed in
rgsabound[0] and the column bounds are passed in rgsabound[1]). Do
not be confused by the ordering that you see when you display a safe
array structure in the debugger.
Finally, keep in mind
that for IOM method calls, lower bounds must always be zero.