I want to use interfaces in my project. Therefore I need some full examples coded in TASM (not MASM) - declaring interfaces, calling methods, using them...

I'll be very happy to see the exmaples include IShellFolder interface.



...thanks Spako
Posted on 2002-03-22 04:37:54 by spako
just using them shouldn't prove to be too hard.


you have to call CreateInstance on the component, call queryinterface on that pointer for the interface you want and then call the various functions.

The vtable is just a large memory array so it's just call for any function.

Making COM objects might prove hard since it requires a specific memory layout. (does TASM produce that layout? :/ )
Posted on 2002-03-22 05:25:56 by Hiroshimator
This short sample written for tasm just gets the ppv for an interface through IUnknown. The same method can be used with other interfaces.




call CLSIDFromProgID, offset ServerName, offset ServerCLSID
call CoCreateInstance, offset ServerCLSID, 0, CLSCTX_SERVER, offset guidIUnknown, offset ppvServer
test eax, eax
jnz CodesoftPreviewError
; Call IUnknown::Addref
mov ebx, [ppvServer]
mov ebp, [ebx]
push ebx
call [ebp+4]
; Call IUnknown::QueryInterface (Get IApplication ppv)
push offset ppvApplication
push offset guidIApplication
push ebx
call [ebp]
; Call IUnknown::Release
push ebx
call [ebp+8]


Hope this help
Posted on 2002-03-22 15:28:16 by acab
If you look at this code...


STDMETHOD  QueryInterface :REFGUID, :PPV
STDMETHOD  AddRef
STDMETHOD  Release

_vtIUnknown  MACRO Cast:REQ
IUnknown STRUC METHOD \
{
  VIRTUAL Cast&_QueryInterface :PTR @Type_QueryInterface
  VIRTUAL Cast&_AddRef            :PTR @Type_AddRef
  VIRTUAL Cast&_Release          :PTR @Type_Release
}
IUnknown  ENDS
pIUnknown  TYPEDEF PTR IUnknown
LPUNKNOWN TYPEDEF PTR IUnknown
ENDM


you see a macro named STDMETHOD which is a C++ naming convention but what the macro does is:

@Type_MethodName PROCTYPE this_:PTR, args is any

It utilizes Tasms built in Naming Convention, fx. the PROCDESC directive produces this code.

MethodName PROCDESC this_:PTR, args is any

@Type_MethodName PROCTYPE this_:PTR, args is any , this is for parameter checking
GLOBAL MethodName:PROC, this makes visibility PUBLIC

So I use this macro to avoid the GLOBAL'isation of evrything, if you use PROCDESC, all methods are realy accessible PUBLIC, I think it's wery anti OOP. The onely methods that need to be declared with the PROCDESC directive, are thous hwo are meant to be static methods fx. the constructor must be static, and frend methods must be declared with the PROCDEC directive, or they can't be accessed. They act as both virtual and static. So now if we derive IUnknown.



_vtISomInterface ¦nbsp; MACRO Cast:REQ
_vtIUnknown Cast

STDMETHOD  GetSomVal :PTR DWORD
STDMETHOD  SetSomVal :DWORD

ISomInterface STRUC IUnknown METHOD \
{
VIRTUAL Cast&_GetSomVal :PTR @Type_GetSomVal
VIRTUAL Cast&_SetSomVal :PTR @Type_SetSomVal
}
ISomInterface ENDS
ENDM

_vtISomInterface ISomInterface



This translates into:



@Type_GetSomVal PROCTYPE this_:PTR, :PTR DWORD
@Type_SetSomVal PROCTYPE this_:PTR, :DWORD

@Table_ISomInterface STRUC
VIRTUAL ISomInterface_QueryInterface :PTR @Type_QueryInterface
VIRTUAL ISomInterface_AddRef :PTR @Type_AddRef
VIRTUAL ISomInterface_Release :PTR @Type_Release
VIRTUAL ISomInterface_GetSomVal :PTR @Type_GetSomVal
VIRTUAL ISomInterface_SetSomVal :PTR @Type_SetSomVal
@Table_ISomInterface ENDS

ISomInterface ¦nbsp; STRUC
@Mptr_IUnknown DD ?
@Mptr_ISomInterface EQU <@Mptr_IUnknown>
ISomInterface ¦nbsp; ENDS



Now if you look at a listing you see that the TABLE datatype is eventualy translated into STRUC datatype, but with the @Table_ prefix, but what I mean is that the virtual method table, is not a part of data directly, but is meant to get accessed through the @Mptr_ data field. But Interfaces are never Instansiated, unless you Implement youre own Interfaces, onely Virtual methods become members of the Virtual Method Table, static Methods must be declared with PROCDESC, if that vas not the case, thera were no Private static methods. So let's make a class.



$CSomClass PROCDESC InitVal:DWORD
@CSomClass PROCDESC this_:PTR
Afrend PROCDESC this_:PTR, ppv:PPV
STDMETHOD GetSomMore :PTR LPSTR
STDMETHOD SetSomMore :LPSTR

_vtCSomClass MACRO Cast:REQ
_vtISomInterface Cast
CSomClass STRUC ISomInterface METHODS \
{
  Cast&_$&Cast :PTR @Type_$CSomClass = $CSomClass  ; Constructor
Cast&_@&Cast :PTR @Type_@CSomClass = @CSomClass ; Destructor
VIRTUAL Cast&_QueryInterface :PTR @Type_QueryInterface= QueryInterface
VIRTUAL Cast&_AddRef :PTR @Type_AddRef  = AddRef
VIRTUAL Cast&_Release :PTR @Type_Release = Release
VIRTUAL Cast&_GetSomVal :PTR @Type_GetSomVal = GetSomVal
VIRTUAL Cast&_SetSomVal :PTR @Type_SetSomVal = SetSomVal
VIRTUAL Cast&_Afrend :PTR @Type_Afrend = Afrend  ; Frend Method
VIRTUAL Cast&_GetSomMore :PTR @Type_GetSomMore = GetSomMore ; Private Virtual Method
VIRTUAL Cast&_SetSomMore :PTR @Type_SetSomMore  = SetSomMore ; - do -
}
LPSTR TYPEDEF PTR BYTE
m_SomVal DWORD ?
m_SomMore LPSTR ?
m_RefCount DWORD ?
CSomClass ENDS
pCSomClass TYPEDEF PTR CSomClass
LPSOMCLASS TYPEDEF PTR CSomClass
ENDM

_vtCSomClass CSomClass

.data
TBLINST
Me CSomClass {@Mptr_IUnknown=@TableAddr_CSomClass, \
                      m_SomVal=0, m_SomMore=0, m_RefCount=1}
.code




This is ofcource just a general idé, but many C++ classes are not much more advanced than this, in the prinsiple. But we are not alowed to put instructions that produce code into structures. Hopefully somthing vas of use.
Posted on 2006-04-04 05:10:27 by polli