what is the correct asm version of the VARIANT Struc?
(located in oaidl.h)
Posted on 2001-11-29 08:58:11 by beaster
this one worked in my source codes so far:



VARIANT struct
vt VARTYPE VT_EMPTY
wReserved1 WORD 0
wReserved2 WORD 0
wReserved3 WORD 0
Union
lVal SDWORD ? ; VT_I4
bVal BYTE ? ; VT_UI1
iVal SWORD ? ; VT_I2
fltVal REAL4 ? ; VT_R4
dblVal REAL8 ? ; VT_R8
boolVal VARIANT_BOOL ? ; VT_BOOL
scode SCODE ? ; VT_ERROR
cyVal QWORD ? ; VT_CY
date QWORD ? ; VT_DATE
bstrVal BSTR ? ; VT_BSTR
punkVal PVOID ? ; VT_UNKNOWN
pdispVal PVOID ? ; VT_DISPATCH
parray PVOID ? ; VT_ARRAY
pbVal PVOID ? ; VT_BYREF|VT_UI1
piVal PVOID ? ; VT_BYREF|VT_I2
plVal PVOID ? ; VT_BYREF|VT_I4
pfltVal PVOID ? ; VT_BYREF|VT_R4
pdblVal PVOID ? ; VT_BYREF|VT_R8
pboolVal PVOID ? ; VT_BYREF|VT_BOOL
pscode PVOID ? ; VT_BYREF|VT_ERROR
pcyVal PVOID ? ; VT_BYREF|VT_CY
pdate PVOID ? ; VT_BYREF|VT_DATE
pbstrVal PVOID ? ; VT_BYREF|VT_BSTR
ppunkVal PVOID ? ; VT_BYREF|VT_UNKNOWN
ppdispVal PVOID ? ; VT_BYREF|VT_DISPATCH
pparray PVOID ? ; VT_BYREF|VT_ARRAY
pvarVal PVOID ? ; VT_BYREF|VT_VARIANT
byref PVOID ? ; Generic ByRef
cVal SBYTE ? ; VT_I1
uiVal WORD ? ; VT_UI2
ulVal DWORD ? ; VT_UI4
intVal SDWORD ? ; VT_int
uintVal DWORD ? ; VT_uint
pdecVal PVOID ? ; VT_BYREF|VT_DECIMAL
pcVal PVOID ? ; VT_BYREF|VT_I1
puiVal PVOID ? ; VT_BYREF|VT_UI2
pulVal PVOID ? ; VT_BYREF|VT_UI4
pintVal PVOID ? ; VT_BYREF|VT_int
puintVal PVOID ? ; VT_BYREF|VT_uint
ENDS
VARIANT ENDS
Posted on 2001-11-29 10:31:45 by japheth
Now why didn't you peek inside oaidl.inc? The def is lurking in there.

There's not much I've published using variants. asmctrl uses a few here and there (but that was never properly documented, it's just code).

Just be sure to initialize them before you use them



Something Proc
LOCAL var:VARIANT
mov var.vt, VT_I4
mov var.lVal, 0
coinvoke pPropBag, IPropertyBag, Read, ADDR wszValue, ADDR var, NULL
ENDP
Posted on 2001-11-29 21:20:32 by Ernie
> The def is lurking in there

That's it :) I watched the lurk in the C file ...

There is a wired define in the C file, with a naming flag, that names parts of the struc with additional names,
in the C test I made, I had to write:

variable.n1.n2.vt = VT_I4 ;

If I define some compiler flags, I can omit the n1, n2.
The version of japheth is equal to my considerations,
I only needed to ensure myself.
Posted on 2001-12-03 07:08:08 by beaster
Read and these pages:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/automat/htm/chap7_5alv.asp

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/automat/htm/chap7_0rn7.asp

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/automat/htm/chap7_5dyr.asp

They will help set the record straight. Vairants are basically a single structure that carries up to 8 bytes of data and a 2 byte word telling any COM function what the data is, so the function can then decided what it needs to do with the data. The idea of a union is more of a HLL issue than an assembler one. I typically always use:

mov variant.lVal, data

Weather its a byte, word, dword, or qword. It doesnt matter how YOU fill it with data. What does matter is what you call the data. You must be accurate with the .vt field (2 byte word describing the data).

ie. i can fill in a variant like so:

mov variant.vt, VT_BYTE
mov variant.lVal, eax

Im saying its only a byte, but im placing 4 bytes (eax) into the structure. It doesnt matter how i fill it, when i pass this variant to a COM object it will read the "VT_BYTE" and go, oh! ok, and take only the 'al' (first byte) from the 4 bytes i put in. The rest (7 bytes in total) is absolutely ignored.

Thast why im telling you not to get too hung up on the UNION business. Its more for C++ compilers (which is why i dont like such things. I dont like the need to learn how to talk to a program, to make a program. C++ as a program get confused if you dont declair for it all the possible uses on 8 bytes, irregardless of your intentions. This is why there is a need for a UNION).

At an assemly level and useage, this is will work justs as well (however there is more onus on you to ensure your filling the 8 bytes correctly (data)):

VARIANT STRUC

variant_type WORD ?
reserved WORD ?
reserved2 DWORD ?
data BYTE 8 dup (?)
VAIRANT ENDS

To create an integer variant with 14 in it:

.data?
var VARIANT <>

.code
mov var.variant_type, VT_I4
lea edx, var.data
mov DWORD PTR [edx], 14


The same thing in the C++ convension would be:



.data?
var VARIANT <>

.code
mov var.vt, VT_I4
mov var.lVal, 14


One less line of code, cause the UNION tells the compiler that when lVal is chosen it implies DWORD PTR automatically (by its definiton in the union).

So in the end, tomato, tomauto, whatever is your flavour. Just provide the data where it counts, how you get there doesnt matter.


Hope this adds some clarity.
:alright:
NaN
Posted on 2003-03-15 21:43:53 by NaN