` Printed Icetips Article

Icetips Article



Par2: Variant
2001-10-04 -- Andrew Ireland
 
> Does clarion have a variant type?

Just treat is as a group and pass by address. Where you need to pass by value, I have some
Asm code that puts a whole in the
stack and pushes the data on so those methods can be called. Attached is code, below
example etc..

The following example calls the ADO Recordset Seek method. This is because you can't
simply push it in a thread safe way any
other way and you need to use the group rather than the built in type so you have the
control you need without the datatype
conversion code in the RTL getting in the way. The tVariant structure can be found in the
ai_comdef.inc file. A brief
explanation of the structures follows the example....

CRecordSet21.Seek procedure(*tVariant vtKeyValues, long SeekOption)

Offs            long
hr              HRESULT
pFunc           long
pRst            long

  code
    pFunc = address(self.IRst21.raw_Seek)
    pRst = address(self.IRst21)
    Offs = PushLong(Offs, SeekOption)
    Offs = PushVariant(Offs, address(vtKeyValues))
    Offs = PushLong(Offs, pRst)
    hr = AdjustStackCallAndClean(Offs, pFunc)
    return hr

The srVal over iVal is needed for 4 byte real values coming back from something like ADO
else the value gets messed up. See the
next explanation. iVal recieves all values of a 4 byte size such as VT_BSTR, VT_I4  etc.
BSTR values are pointers and need
converting to clarion cstrings using API functions.

tVariant                group,type
vt                        short
wReserved1                short
wReserved2                short
wReserved3                short
iVal                      long
iVal2                     long
srVal                     sreal,over(iVal)
                        end

This is a variation of the tVariant specifically for a real as this is needed when reading
real values into a variant from
something like ADO or clarion will use it's type conversion and mess up the value.

tVariantr               group,type
vt                        short
wReserved1                short
wReserved2                short
wReserved3                short
rVal                      real
                        end

The following is needed for omitable params, nothing else will do less you receive an
error.

vtMissing               group
vt                        short(VT_ERROR)
wReserved1                short
wReserved2                short
wReserved3                short
iVal                      long(DISP_E_PARAMNOTFOUND)
pad                       long
                        end

Here's how to compile in the ASM code...

SupFnc      class,link('supfnc.a', _COMLinkMode_),dll(_COMDllMode_)
                  end

    module('supfnc.a')
      AdjustStackCallAndClean(long dwSize, long
pFunc),long,name('_AdjustStackCallAndClean')
      PushLong(long Offs, long iVal),long,name('_PushLong')
      PushVariant(long Offs, long pvt),long,name('_PushVariant')
    end

Only functions that pass them by value need this, all others I have encountered in COM do
not need anything special doing. But
if it is needed, all params must be pushed this way. Thankfully they are all either longs
or variants. It's a quick dirty hack
but works nonetheless.



Printed November 23, 2024, 2:23 am
This article has been viewed/printed 35230 times.