`
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. |