`
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 October 24, 2026, 3:06 pm This article has been viewed/printed 36252 times. |