News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Passing pointers to COM objects to functions

Started by Fredericvo, May 01, 2012, 11:04:52 PM

Previous topic - Next topic

Fredericvo

After studying lots of DirectX tutorials I noticed a tendency to keep many pointers as globals, which is a quick and dirty way to get started but after a while I wondered how one could create these, say, in WinMain and pass a reference to them in functions, and allow the callee to modify/create them. I've sweated and struggled a whole afternoon but finally came up with a solution, after careful analysis of the ASM output

Say I have the following in winmain, rather than as globals:

LPDIRECT3D9 d3d=NULL; // pointer to interface
LPDIRECT3DDEVICE9 d3ddev=NULL; // pointer to device class

Then I would call an init() function, actually declared as VOID init(HWND hwnd, LPDIRECT3D9  *d3d, LPDIRECT3DDEVICE9 *d3ddev);

Inside the init I would then do the following:

*d3d = Direct3DCreate9(D3D_SDK_VERSION); // notice the asterisk here

fill in D3DPRESENT_PARAMETERS struct d3dpp

(*d3d)->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, d3ddev); // dereference it first

From now on you can use the device like so:

(*d3ddev)->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX), 0, CUSTOMFVF, D3DPOOL_MANAGED,  &v_buffer, NULL); //v_buffer is still a global with this example

As you can see not using globals adds lots of overhead and mind-bending pointer logic.
Every function you call needs to be passed the address of the pointer(s) to the object(s) you will use.
These functions need to be declared correctly with a ptr-to-ptr (LP prefixed variables are ALREADY pointers so only one asterisk!)

Not sure if this is helpful but it sure was a good pointer exercise for me  :dazzled:



jj2007

In assembler, you would typically pass a pointer to a global structure:
include \masm32\include\masm32rt.inc

.code
rc RECT <12, 34, 56, 78>

MyTest proc argRc:DWORD
  mov eax, argRc
  MsgBox 0, str$([eax.RECT.right]), "rc.right:", MB_OK
  ret
MyTest endp

start:
invoke MyTest, offset rc
exit
end start