To begin using AppConn in your C++ project, the AppConn COM control must be imported into the project using the VC++ compiler. To import the appConn.dll, installed to the \Winnt\System32 folder by default, place the following import statement at the beginning of the source file that will be using the AppConn component:
#import "appconn.dll"
The import command will generate two new files, appconn.tlh and appconn.tli, which are automatically included in the source file. The appconn.tlh file defines wrapper classes for each of the AppConn interfaces, smart pointers for the wrapper classes, and all of the AppConn constants inside of the namespace AppConnLib. To use the AppConn definitions, the AppConn definition must be prefaced with AppConnLib:: or by including a using namespace statement:
using namespace AppConnLib;
AppConn objects are accessed using the smart pointer to the wrapper class. The smart pointer will perform all of the life time management for the object. When an object is assigned to the smart pointer, the smart pointer will call AddRef on the object. When the pointer is reassigned, the smart pointer will call Release on the object, and when the smart pointer is destroyed it will call Release on the object. The smart pointer's name is the name of the interface with the suffix "Ptr". For example, declare an interface pointer with the following statement:
IAppConnTablePtr pTable;
To create an AppConn object, use the smart pointer CreateInstance
method passing the class Id, which can be obtained using the __uuidof keyword
with the class name. CreateInstance
will return an HRESULT, which
can be checked for success or failure.
hr = pSession.CreateInstance(__uuidof(AppConnTable));
The wrapper class creates a wrapper method for each object method.
The methods do not return an HRESULT the way COM method normally do, but will
throw the exception _com_error if the call fails, so all calls should be placed
inside a try/catch block. The _com_error exception contains the ErrorInfo for
the error that occurred. Optional parameters which are declared as _variant_t
have a default parameter, so they may be omitted. The wrapper class replaces
BSTR parameters with the wrapper class _bstr_t and VARIANT parameters with the
wrapper class _variant_t. _bstr_t contains a BSTR and will automatically convert
from char *, wchar_t *, BSTR, and _variant_t. _bstr_ will call SysAllocString
to create the internal string, and will call SysFreeString to destroy the string
when a new value is assigned or when it is destroyed. _variant_t contains a
VARIANT and will automatically convert values that can be stored as a VARIANT.
_variant_t will call VariantClear to destroy the variant when a new value is
assigned or when it is destroyed. By changing BSTR and VARIANT to the wrapper
classes, parameters can be passed to the method as primitive COM pointer or
printf type and the compiler will handle conversion and life type management.
Methods will return the COM return value directly instead of as the last parameter
of the parameter list as COM methods normally do.
try { pSession->ConnectToModel("localhost","CCSDemo","bjones","bjones"); } catch (_com_error &err) { printf("Error: %s\n", OLE2A((LPOLESTR) err.Description())); }
_bstr_t bstrString; try { bstrString = pSession->GetStringAtOffset(10, 5); } catch (_com_error &err) { printf("Error: %s\n", OLE2A((LPOLESTR) err.Description())); }
The wrapper class also declares properties which the compiler treats as data
members by changing their references into function calls. The properties can
be treated like data members.
VARIANT_BOOL bConnect = pSession->IsConnected
The wrapper class also declares properties with parameters. In the following
example, Item is a property of AppConnStringMap which handles both get and put
with an index that can be either a string or an number. Put with a string
will add the key/value if the key does not exist and replace the value if the
key does exist. Put with a number will replace the value if the index exists
and throw an error if it does not.
IAppConnStringMapPtr pAttributes;
pAttributes.CreateInstance(__uuidof(AppConnStringMap));
pAttributes->Item["LastName"] = "S";
bstrt bstrLastName = pAttributes->Item[1];
The following example demonstrates the different ways the wrapper classes can
be used to simplify using the AppConn objects. The first line inside the try
block creates an instance of AppConnStringList assigned to pSelectFields. Because
pSelectFields is declared as a smart pointer life time management will be done
automatically and the object will be destroyed when pSelectFields goes out of
scope. The second line inside the try block adds an entry to pFilter with the
key "LastName" and value "Brown". Because the parameters
to Add are declared as _bstr_t in the wrapper class the parameters will automatically
be converted from char * to BSTR and cleaned up. The third line inside the try
block executes the PerformTableProcedure method which will return an AppConnRecordSet.
The value is assigned to pRecords which is a smart pointer. If the return value
is not assigned to a variable the AppConnRecordSet will be destroyed automatically.
The first two parameters of PerformTableProcedure are declared as _bstr_t, so
AppConn will automatically convert the parameters from char * to BSTR and clean
up the values after the method call. The next five parameters are optional so
they could be omitted and are declared as _variant_t in the wrapper class. The
fourth parameter is included in the method call, so all the parameters up to
the fourth parameter must be included. The third parameter is declared inline
as an instance of _variant_t, which will create an empty parameter and be handled
as if it is omitted. The fourth parameter is passed as a smart pointer which
_variant_t will automatically convert to a VARIANT and clean up the value when
it is done. The for loop will iterate over each of the records in the recordset
using the Count property declared in the AppConnRecordSet wrapper class to get
number of records. The Item property declared in the AppConnRecordSet is used
to assign each record to pRecord. The Detach method must be called on the smart
pointer before assigning a value to pRecord; otherwise, it will cause an assert.
IAppConnRecordSetPtr pRecords; IAppConnStringMapPtr pFilter; IAppConnModelRecordPtr pRecord; try { pFilter.CreateInstance(__uuidof(AppConnStringMap)); pFilter ->Add("LastName", "Brown"); pRecords = pSession->PerformTableProcedure("Person", "GetPerson", _variant_t(), pFilter); for (long i = 0; i < pRecords->Count; i++) { pRecord = pRecords->Item[i]; pRecord.Detach(); } } catch (_com_error &err) { printf("Error: %s\n", OLE2A((LPOLESTR) err.Description())); }
© 1999-2007 Attachmate Corporation. All rights reserved. Terms of Use.