1. Computing
Send to a Friend via Email
An Introduction to COM Programming with Delphi (5 / 6)
Page 1: Marshaling Data. Oh, the glory of leadership! Variant Reference Page.
 More of this Feature
• Page 2: Using Variants and Variant Arrays
• Page 3: Homework Assignment
 More Delphi COM Lessons
• TOC
• Lesson 1
• Lesson 2
• Lesson 3
• Lesson 4
• Lesson 6
 Join the Discussion
"Post your views, comments, questions and doubts to this article."
Discuss!
 Related Resources
• COM / OLE / ActiveX programming with Delphi

Article written by Curtis Socha, brought to you by Zarko Gajic.

Oh, the glory of leadership!

The act of moving data across program boundaries is called Marshaling. When you are using a DLL on your local machine, the objects and functions you create are inside the address space of the calling program. Therefore, you don’t really have to worry about marshaling any data because it is already within your program address space. You are within program boundaries. This all changes when we start talking about out-of-process servers like automation and DCom of course.

Automation servers reside in their own program address space, and DCom objects are obviously not even on the same computer. In this situation, marshaling data becomes necessary because you usually cannot read or write to a variable declared in a different address space. Fortunately for us, Windows will take care of a good part of the marshaling behind the scenes. All that Windows asks is that you use data types that it knows how to marshal. Sounds simple, eh?

Simple as it may sound, we run into another big problem when it comes to marshaling. Records and arrays. How do we move record structures to and from Com objects? How do you move an array of structures? The answer is Variant Arrays.

Hint: To see a list of data types that can be automatically marshaled, view the listing from the 4th class. Any types that have Automation set to "Yes" are automatically marshaled.

All of this hard earned knowledge will finally be put to use, by creating ...

Behold the power of Variants

As you have probably already figured out, a variant can hold just about any type of data. Variants play a crucial role in programming COM programming. They are considered to be the equivalent of the safe arrays used for OLE Automation. Although using variants will severely impede machine performance, they allow you to do things you normally could not do without considerable effort.

Variant Reference Page
The Variant Reference Page is a compilation of variant information I gathered after spending 2 hours exploring System.Pas. It is worth delving into this unit for a few hours to see how the masters at Borland encapsulated the entire world of variants into just a handful of functions and procedures. Unfortunately, they did not make them easy to find in the Delphi Help. In order to make your life easier, I built this reference page.

Variant types

VarType (Value) Contents of Variant
varEmpty ($0000) The variant is Unassigned
varNull ($0001) The variant is Null
varSmallint ($0002) 16-bit signed integer (type Smallint).
varInteger ($0003) 32-bit signed integer (type Integer).
varSingle ($0004) Single-precision floating-point value (type Single).
varDouble ($0005) Double-precision floating-point value (type Double).
varCurrency ($0006) Currency floating-point (type Currency). Default floats are type currency.
varDate ($0007) Date and time value (type TDateTime).
varOLEStr ($0008) Reference to a dynamically allocated UNICODE string. (PWideChar)
varDispatch ($0009) Reference to an Automation object (an IDispatch interface pointer).
varError ($000A) Operating system error code. (type LongWord)
varBoolean ($000B) 16-bit boolean (type WordBool).
varVariant ($000C) Holds a 16 byte variant. Variants can contain variants!
varUnknown ($000D) Reference to an unknown COM object (IUnknown interface pointer).
varByte ($0011) 8-bit unsigned integer (type Byte).
varStrArg ($0048) ? I cannot figure out what this is for.
varString ($0100) Reference to a dynamically allocated Pascal string (type AnsiString).
varAny ($0101) A pointer. Use only to pass to Corba functions.
varTypeMask ($0FFF) Bit mask for extracting type code.
varArray ($2000) Bit indicating variant array. (type PVarArray)
varByRef ($4000) Bit indicating variant contains a reference (rather than a value).

Variant Manipulation

Methood #13#10 Usage #13#10 Description
VarArrayCreate
V := VarArrayCreate([0, 5, 0, 3], varInteger);
Creates an array[0..5, 0..3] of integer.
VarArrayDimCount
MyInt := VarArrayDimCount(V);
//Returns the dimensions if is a variant array
VarArrayHighBound
MyHighBound := VarArrayHighBound(V, 1);
Returns high boundary of 1st dimension.
VarArrayOf
V := VarArrayOf([1, ‘Hello Word’, 13.23);
Creates a filled array[0..2] of variant.
VarArrayLock
MyArrayPtr := VarArrayLock (V);
Locks the v array into standard Delphi type
VarArrayLowBound
MyLowBound := VarArrayLowBound(V, 1);
Returns low boundary of the 1st dimension.
VarArrayReDim
VarArrayReDim(V, 5);
Resizes V arrays rightmost dimension to 5.
VarArrayRef
SomeWinApiCall(VarArrayRef(V));
Pass reference of variant array to Win API.
VarArrayUnLock
VarArrayLock (V);
Unlocks a variant array.
VarAsType
V := VarAsType(V, varString);
will convert V into a varString VarType
VarClear
VarClear(V);
Sets V to unassigned.
VarFromDateTime
V := VarFromDateTime(MyDateTime);
Converts a TDateTime to a variant type.
VarIsArray
if VarIsArray(V) then showmessage(‘V is Array!’);
Tests to see if a variant is of varArray.
VarIsEmpty
if VarIsEmpty(V) then ShowMessage(‘Empty!’);
Tests to see if set to varEmpty or if it is varDispatch / varUnknown and is nil.
VarIsNull
if VarIsNull(V) then ShowMessage(‘It’s Null!’);
Tests to see if a variant is set to varNull
VarToDateTime
MyDateTime := VarToDateTime(V);
Converts variant to a TDateTime type.
VarToStr
ShowMessage(VarToStr(V));
Converts Variant to Str. Error checks it 1st.
VarType
SomeInt := VarType(V) and varTypeMask;
Will return the VarType of the variant

Note 1: Look in System.Pas for variant support functions not listed in the Delphi Help!
Note 2: V is declared as a type Variant.
Note 3: Use OLEVariant when you want to use only COM-Compatible types.

Next page > Using Variants and Variant Arrays > Page 1, 2, 3

An Introduction to COM Programming with Delphi: Table of Content
<< Previous Lesson (4): A Com Object walk-a-bout. A Class Factory tour. Our first true COM Object program.
>> Last Lesson (6): Let's see how to make your first Type Library using Delphi.

 

©2014 About.com. All rights reserved.