Back to index

php5  5.3.10
Classes | Defines | Functions | Variables
com_wrapper.c File Reference
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_com_dotnet.h"
#include "php_com_dotnet_internal.h"

Go to the source code of this file.

Classes

struct  php_dispatchex

Defines

#define TSRMLS_FIXED()
#define FETCH_DISP(methname)

Functions

static void disp_destructor (php_dispatchex *disp)
static void dispatch_dtor (zend_rsrc_list_entry *rsrc TSRMLS_DC)
int php_com_wrapper_minit (INIT_FUNC_ARGS)
static void trace (char *fmt,...)
static HRESULT STDMETHODCALLTYPE disp_queryinterface (IDispatchEx *This, REFIID riid, void **ppvObject)
static ULONG STDMETHODCALLTYPE disp_addref (IDispatchEx *This)
static ULONG STDMETHODCALLTYPE disp_release (IDispatchEx *This)
static HRESULT STDMETHODCALLTYPE disp_gettypeinfocount (IDispatchEx *This, UINT *pctinfo)
static HRESULT STDMETHODCALLTYPE disp_gettypeinfo (IDispatchEx *This, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
static HRESULT STDMETHODCALLTYPE disp_getidsofnames (IDispatchEx *This, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
static HRESULT STDMETHODCALLTYPE disp_invoke (IDispatchEx *This, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
static HRESULT STDMETHODCALLTYPE disp_getdispid (IDispatchEx *This, BSTR bstrName, DWORD grfdex, DISPID *pid)
static HRESULT STDMETHODCALLTYPE disp_invokeex (IDispatchEx *This, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
static HRESULT STDMETHODCALLTYPE disp_deletememberbyname (IDispatchEx *This, BSTR bstrName, DWORD grfdex)
static HRESULT STDMETHODCALLTYPE disp_deletememberbydispid (IDispatchEx *This, DISPID id)
static HRESULT STDMETHODCALLTYPE disp_getmemberproperties (IDispatchEx *This, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
static HRESULT STDMETHODCALLTYPE disp_getmembername (IDispatchEx *This, DISPID id, BSTR *pbstrName)
static HRESULT STDMETHODCALLTYPE disp_getnextdispid (IDispatchEx *This, DWORD grfdex, DISPID id, DISPID *pid)
static HRESULT STDMETHODCALLTYPE disp_getnamespaceparent (IDispatchEx *This, IUnknown **ppunk)
static void generate_dispids (php_dispatchex *disp TSRMLS_DC)
static php_dispatchexdisp_constructor (zval *object TSRMLS_DC)
PHPAPI IDispatch * php_com_wrapper_export_as_sink (zval *val, GUID *sinkid, HashTable *id_to_name TSRMLS_DC)
PHPAPI IDispatch * php_com_wrapper_export (zval *val TSRMLS_DC)

Variables

static int le_dispatch
static struct IDispatchExVtbl

Class Documentation

struct php_dispatchex

Definition at line 34 of file com_wrapper.c.

Collaboration diagram for php_dispatchex:
Class Members
HashTable * dispid_to_name
DWORD engine_thread
int id
CONST_VTBL struct IDispatchExVtbl * lpVtbl
HashTable * name_to_dispid
zval * object
LONG refcount
GUID sinkid

Define Documentation

#define FETCH_DISP (   methname)
Value:
TSRMLS_FIXED()                                                                                                                                                          \
	php_dispatchex *disp = (php_dispatchex*)This;                                                                                              \
       if (COMG(rshutdown_started)) {                                                                                                                            \
              trace(" PHP Object:%p (name:unknown) %s\n", disp->object,  methname);                                                  \
       } else {                                                                                                                                                                \
              trace(" PHP Object:%p (name:%s) %s\n", disp->object, Z_OBJCE_P(disp->object)->name, methname);    \
       }                                                                                                                                                                              \
       if (GetCurrentThreadId() != disp->engine_thread) {                                                                                          \
              return RPC_E_WRONG_THREAD;                                                                                                                         \
       }

Definition at line 95 of file com_wrapper.c.

#define TSRMLS_FIXED ( )

Definition at line 92 of file com_wrapper.c.


Function Documentation

static ULONG STDMETHODCALLTYPE disp_addref ( IDispatchEx *  This) [static]

Definition at line 127 of file com_wrapper.c.

{
       FETCH_DISP("AddRef");

       return InterlockedIncrement(&disp->refcount);
}
static php_dispatchex* disp_constructor ( zval *object  TSRMLS_DC) [static]

Definition at line 537 of file com_wrapper.c.

{
       php_dispatchex *disp = (php_dispatchex*)CoTaskMemAlloc(sizeof(php_dispatchex));

       trace("constructing a COM wrapper for PHP object %p (%s)\n", object, Z_OBJCE_P(object)->name);
       
       if (disp == NULL)
              return NULL;

       memset(disp, 0, sizeof(php_dispatchex));

       disp->engine_thread = GetCurrentThreadId();
       disp->lpVtbl = &php_dispatch_vtbl;
       disp->refcount = 1;


       if (object)
              Z_ADDREF_P(object);
       disp->object = object;

       disp->id = zend_list_insert(disp, le_dispatch);
       
       return disp;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static HRESULT STDMETHODCALLTYPE disp_deletememberbydispid ( IDispatchEx *  This,
DISPID  id 
) [static]

Definition at line 367 of file com_wrapper.c.

{
       FETCH_DISP("DeleteMemberByDispID");
       
       /* TODO: unset */
       
       return S_FALSE;
}
static HRESULT STDMETHODCALLTYPE disp_deletememberbyname ( IDispatchEx *  This,
BSTR  bstrName,
DWORD  grfdex 
) [static]

Definition at line 355 of file com_wrapper.c.

{
       FETCH_DISP("DeleteMemberByName");

       /* TODO: unset */

       return S_FALSE;
}
static void disp_destructor ( php_dispatchex disp) [static]

Definition at line 562 of file com_wrapper.c.

{
       TSRMLS_FETCH();
       
       /* Object store not available during request shutdown */
       if (COMG(rshutdown_started)) {
              trace("destroying COM wrapper for PHP object %p (name:unknown)\n", disp->object);
       } else {
              trace("destroying COM wrapper for PHP object %p (name:%s)\n", disp->object, Z_OBJCE_P(disp->object)->name);
       }
       
       disp->id = 0;
       
       if (disp->refcount > 0)
              CoDisconnectObject((IUnknown*)disp, 0);

       zend_hash_destroy(disp->dispid_to_name);
       zend_hash_destroy(disp->name_to_dispid);
       FREE_HASHTABLE(disp->dispid_to_name);
       FREE_HASHTABLE(disp->name_to_dispid);
                     
       if (disp->object)
              zval_ptr_dtor(&disp->object);

       CoTaskMemFree(disp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static HRESULT STDMETHODCALLTYPE disp_getdispid ( IDispatchEx *  This,
BSTR  bstrName,
DWORD  grfdex,
DISPID *  pid 
) [static]

Definition at line 221 of file com_wrapper.c.

{
       HRESULT ret = DISP_E_UNKNOWNNAME;
       char *name;
       unsigned int namelen;
       zval **tmp;
       FETCH_DISP("GetDispID");

       name = php_com_olestring_to_string(bstrName, &namelen, COMG(code_page) TSRMLS_CC);

       trace("Looking for %s, namelen=%d in %p\n", name, namelen, disp->name_to_dispid);
       
       /* Lookup the name in the hash */
       if (zend_hash_find(disp->name_to_dispid, name, namelen+1, (void**)&tmp) == SUCCESS) {
              trace("found it\n");
              *pid = Z_LVAL_PP(tmp);
              ret = S_OK;
       }

       efree(name);
       
       return ret;
}

Here is the call graph for this function:

static HRESULT STDMETHODCALLTYPE disp_getidsofnames ( IDispatchEx *  This,
REFIID  riid,
LPOLESTR *  rgszNames,
UINT  cNames,
LCID  lcid,
DISPID *  rgDispId 
) [static]

Definition at line 171 of file com_wrapper.c.

{
       UINT i;
       HRESULT ret = S_OK;
       FETCH_DISP("GetIDsOfNames");

       for (i = 0; i < cNames; i++) {
              char *name;
              unsigned int namelen;
              zval **tmp;
              
              name = php_com_olestring_to_string(rgszNames[i], &namelen, COMG(code_page) TSRMLS_CC);
              
              /* Lookup the name in the hash */
              if (zend_hash_find(disp->name_to_dispid, name, namelen+1, (void**)&tmp) == FAILURE) {
                     ret = DISP_E_UNKNOWNNAME;
                     rgDispId[i] = 0;
              } else {
                     rgDispId[i] = Z_LVAL_PP(tmp);
              }

              efree(name);

       }
       
       return ret;
}

Here is the call graph for this function:

static HRESULT STDMETHODCALLTYPE disp_getmembername ( IDispatchEx *  This,
DISPID  id,
BSTR *  pbstrName 
) [static]

Definition at line 389 of file com_wrapper.c.

{
       zval *name;
       FETCH_DISP("GetMemberName");

       if (SUCCESS == zend_hash_index_find(disp->dispid_to_name, id, (void**)&name)) {
              OLECHAR *olestr = php_com_string_to_olestring(Z_STRVAL_P(name), Z_STRLEN_P(name), COMG(code_page) TSRMLS_CC);
              *pbstrName = SysAllocString(olestr);
              efree(olestr);
              return S_OK;
       } else {
              return DISP_E_UNKNOWNNAME;
       }
}

Here is the call graph for this function:

static HRESULT STDMETHODCALLTYPE disp_getmemberproperties ( IDispatchEx *  This,
DISPID  id,
DWORD  grfdexFetch,
DWORD pgrfdex 
) [static]

Definition at line 378 of file com_wrapper.c.

{
       FETCH_DISP("GetMemberProperties");

       return DISP_E_UNKNOWNNAME;
}
static HRESULT STDMETHODCALLTYPE disp_getnamespaceparent ( IDispatchEx *  This,
IUnknown **  ppunk 
) [static]

Definition at line 426 of file com_wrapper.c.

{
       FETCH_DISP("GetNameSpaceParent");

       *ppunk = NULL;
       return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE disp_getnextdispid ( IDispatchEx *  This,
DWORD  grfdex,
DISPID  id,
DISPID *  pid 
) [static]

Definition at line 407 of file com_wrapper.c.

{
       ulong next = id+1;
       FETCH_DISP("GetNextDispID");

       while(!zend_hash_index_exists(disp->dispid_to_name, next))
              next++;

       if (zend_hash_index_exists(disp->dispid_to_name, next)) {
              *pid = next;
              return S_OK;
       }
       return S_FALSE;
}

Here is the call graph for this function:

static HRESULT STDMETHODCALLTYPE disp_gettypeinfo ( IDispatchEx *  This,
UINT  iTInfo,
LCID  lcid,
ITypeInfo **  ppTInfo 
) [static]

Definition at line 159 of file com_wrapper.c.

{
       FETCH_DISP("GetTypeInfo");
       
       *ppTInfo = NULL;
       return DISP_E_BADINDEX;
}
static HRESULT STDMETHODCALLTYPE disp_gettypeinfocount ( IDispatchEx *  This,
UINT *  pctinfo 
) [static]

Definition at line 149 of file com_wrapper.c.

{
       FETCH_DISP("GetTypeInfoCount");

       *pctinfo = 0;
       return S_OK;
}
static HRESULT STDMETHODCALLTYPE disp_invoke ( IDispatchEx *  This,
DISPID  dispIdMember,
REFIID  riid,
LCID  lcid,
WORD  wFlags,
DISPPARAMS *  pDispParams,
VARIANT *  pVarResult,
EXCEPINFO *  pExcepInfo,
UINT *  puArgErr 
) [static]

Definition at line 205 of file com_wrapper.c.

{
       return This->lpVtbl->InvokeEx(This, dispIdMember,
                     lcid, wFlags, pDispParams,
                     pVarResult, pExcepInfo, NULL);
}
static HRESULT STDMETHODCALLTYPE disp_invokeex ( IDispatchEx *  This,
DISPID  id,
LCID  lcid,
WORD  wFlags,
DISPPARAMS *  pdp,
VARIANT *  pvarRes,
EXCEPINFO *  pei,
IServiceProvider *  pspCaller 
) [static]

Definition at line 249 of file com_wrapper.c.

{
       zval **name;
       UINT i;
       zval *retval = NULL;
       zval ***params = NULL;
       HRESULT ret = DISP_E_MEMBERNOTFOUND;
       FETCH_DISP("InvokeEx");

       if (SUCCESS == zend_hash_index_find(disp->dispid_to_name, id, (void**)&name)) {
              /* TODO: add support for overloaded objects */

              trace("-- Invoke: %d %20s [%d] flags=%08x args=%d\n", id, Z_STRVAL_PP(name), Z_STRLEN_PP(name), wFlags, pdp->cArgs);
              
              /* convert args into zvals.
               * Args are in reverse order */
              if (pdp->cArgs) {
                     params = (zval ***)safe_emalloc(sizeof(zval **), pdp->cArgs, 0);
                     for (i = 0; i < pdp->cArgs; i++) {
                            VARIANT *arg;
                            zval *zarg;

                            arg = &pdp->rgvarg[ pdp->cArgs - 1 - i];

                            trace("alloc zval for arg %d VT=%08x\n", i, V_VT(arg));

                            ALLOC_INIT_ZVAL(zarg);
                            php_com_wrap_variant(zarg, arg, COMG(code_page) TSRMLS_CC);
                            params[i] = (zval**)emalloc(sizeof(zval**));
                            *params[i] = zarg;
                     }
              }

              trace("arguments processed, prepare to do some work\n");       
       
              /* TODO: if PHP raises an exception here, we should catch it
               * and expose it as a COM exception */
              
              if (wFlags & DISPATCH_PROPERTYGET) {
                     retval = zend_read_property(Z_OBJCE_P(disp->object), disp->object, Z_STRVAL_PP(name), Z_STRLEN_PP(name)+1, 1 TSRMLS_CC);
              } else if (wFlags & DISPATCH_PROPERTYPUT) {
                     zend_update_property(Z_OBJCE_P(disp->object), disp->object, Z_STRVAL_PP(name), Z_STRLEN_PP(name)+1, *params[0] TSRMLS_CC);
              } else if (wFlags & DISPATCH_METHOD) {
                     zend_try {
                            if (SUCCESS == call_user_function_ex(EG(function_table), &disp->object, *name,
                                                 &retval, pdp->cArgs, params, 1, NULL TSRMLS_CC)) {
                                   ret = S_OK;
                                   trace("function called ok\n");

                                   /* Copy any modified values to callers copy of variant*/
                                   for (i = 0; i < pdp->cArgs; i++) {
                                          php_com_dotnet_object *obj = CDNO_FETCH(*params[i]);
                                          VARIANT *srcvar = &obj->v;
                                          VARIANT *dstvar = &pdp->rgvarg[ pdp->cArgs - 1 - i];
                                          if ((V_VT(dstvar) & VT_BYREF) && obj->modified ) {
                                                 trace("percolate modified value for arg %d VT=%08x\n", i, V_VT(dstvar));
                                                 php_com_copy_variant(dstvar, srcvar TSRMLS_CC);   
                                          }
                                   }
                            } else {
                                   trace("failed to call func\n");
                                   ret = DISP_E_EXCEPTION;
                            }
                     } zend_catch {
                            trace("something blew up\n");
                            ret = DISP_E_EXCEPTION;
                     } zend_end_try();
              } else {
                     trace("Don't know how to handle this invocation %08x\n", wFlags);
              }
       
              /* release arguments */
              if (params) {
                     for (i = 0; i < pdp->cArgs; i++) {
                            zval_ptr_dtor(params[i]);
                            efree(params[i]);
                     }
                     efree(params);
              }
              
              /* return value */
              if (retval) {
                     if (pvarRes) {
                            VariantInit(pvarRes);
                            php_com_variant_from_zval(pvarRes, retval, COMG(code_page) TSRMLS_CC);
                     }
                     zval_ptr_dtor(&retval);
              } else if (pvarRes) {
                     VariantInit(pvarRes);
              }
              
       } else {
              trace("InvokeEx: I don't support DISPID=%d\n", id);
       }

       return ret;
}

Here is the call graph for this function:

static HRESULT STDMETHODCALLTYPE disp_queryinterface ( IDispatchEx *  This,
REFIID  riid,
void **  ppvObject 
) [static]

Definition at line 107 of file com_wrapper.c.

{
       FETCH_DISP("QueryInterface");

       if (IsEqualGUID(&IID_IUnknown, riid) ||
                     IsEqualGUID(&IID_IDispatch, riid) ||
                     IsEqualGUID(&IID_IDispatchEx, riid) ||
                     IsEqualGUID(&disp->sinkid, riid)) {
              *ppvObject = This;
              InterlockedIncrement(&disp->refcount);
              return S_OK;
       }

       *ppvObject = NULL;
       return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE disp_release ( IDispatchEx *  This) [static]

Definition at line 134 of file com_wrapper.c.

{
       ULONG ret;
       FETCH_DISP("Release");

       ret = InterlockedDecrement(&disp->refcount);
       trace("-- refcount now %d\n", ret);
       if (ret == 0) {
              /* destroy it */
              if (disp->id)
                     zend_list_delete(disp->id);
       }
       return ret;
}

Here is the call graph for this function:

static void dispatch_dtor ( zend_rsrc_list_entry *rsrc  TSRMLS_DC) [static]

Definition at line 57 of file com_wrapper.c.

{
       php_dispatchex *disp = (php_dispatchex *)rsrc->ptr;
       disp_destructor(disp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void generate_dispids ( php_dispatchex *disp  TSRMLS_DC) [static]

Definition at line 457 of file com_wrapper.c.

{
       HashPosition pos;
       char *name = NULL;
       zval *tmp;
       int namelen;
       int keytype;
       ulong pid;

       if (disp->dispid_to_name == NULL) {
              ALLOC_HASHTABLE(disp->dispid_to_name);
              ALLOC_HASHTABLE(disp->name_to_dispid);
              zend_hash_init(disp->name_to_dispid, 0, NULL, ZVAL_PTR_DTOR, 0);
              zend_hash_init(disp->dispid_to_name, 0, NULL, ZVAL_PTR_DTOR, 0);
       }

       /* properties */
       if (Z_OBJPROP_P(disp->object)) {
              zend_hash_internal_pointer_reset_ex(Z_OBJPROP_P(disp->object), &pos);
              while (HASH_KEY_NON_EXISTANT != (keytype =
                            zend_hash_get_current_key_ex(Z_OBJPROP_P(disp->object), &name,
                            &namelen, &pid, 0, &pos))) {
                     char namebuf[32];
                     if (keytype == HASH_KEY_IS_LONG) {
                            snprintf(namebuf, sizeof(namebuf), "%d", pid);
                            name = namebuf;
                            namelen = strlen(namebuf)+1;
                     }

                     zend_hash_move_forward_ex(Z_OBJPROP_P(disp->object), &pos);

                     /* Find the existing id */
                     if (zend_hash_find(disp->name_to_dispid, name, namelen, (void**)&tmp) == SUCCESS)
                            continue;

                     /* add the mappings */
                     MAKE_STD_ZVAL(tmp);
                     ZVAL_STRINGL(tmp, name, namelen-1, 1);
                     pid = zend_hash_next_free_element(disp->dispid_to_name);
                     zend_hash_index_update(disp->dispid_to_name, pid, (void*)&tmp, sizeof(zval *), NULL);

                     MAKE_STD_ZVAL(tmp);
                     ZVAL_LONG(tmp, pid);
                     zend_hash_update(disp->name_to_dispid, name, namelen, (void*)&tmp, sizeof(zval *), NULL);
              }
       }
       
       /* functions */
       if (Z_OBJCE_P(disp->object)) {
              zend_hash_internal_pointer_reset_ex(&Z_OBJCE_P(disp->object)->function_table, &pos);
              while (HASH_KEY_NON_EXISTANT != (keytype =
                            zend_hash_get_current_key_ex(&Z_OBJCE_P(disp->object)->function_table,
                            &name, &namelen, &pid, 0, &pos))) {

                     char namebuf[32];
                     if (keytype == HASH_KEY_IS_LONG) {
                            snprintf(namebuf, sizeof(namebuf), "%d", pid);
                            name = namebuf;
                            namelen = strlen(namebuf) + 1;
                     }

                     zend_hash_move_forward_ex(Z_OBJPROP_P(disp->object), &pos);

                     /* Find the existing id */
                     if (zend_hash_find(disp->name_to_dispid, name, namelen, (void**)&tmp) == SUCCESS)
                            continue;

                     /* add the mappings */
                     MAKE_STD_ZVAL(tmp);
                     ZVAL_STRINGL(tmp, name, namelen-1, 1);
                     pid = zend_hash_next_free_element(disp->dispid_to_name);
                     zend_hash_index_update(disp->dispid_to_name, pid, (void*)&tmp, sizeof(zval *), NULL);

                     MAKE_STD_ZVAL(tmp);
                     ZVAL_LONG(tmp, pid);
                     zend_hash_update(disp->name_to_dispid, name, namelen, (void*)&tmp, sizeof(zval *), NULL);
              }
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI IDispatch* php_com_wrapper_export ( zval *val  TSRMLS_DC)

Definition at line 628 of file com_wrapper.c.

{
       php_dispatchex *disp = NULL;

       if (Z_TYPE_P(val) != IS_OBJECT) {
              return NULL;
       }

       if (php_com_is_valid_object(val TSRMLS_CC)) {
              /* pass back its IDispatch directly */
              php_com_dotnet_object *obj = CDNO_FETCH(val);
              
              if (obj == NULL)
                     return NULL;

              if (V_VT(&obj->v) == VT_DISPATCH && V_DISPATCH(&obj->v)) {
                     IDispatch_AddRef(V_DISPATCH(&obj->v));
                     return V_DISPATCH(&obj->v);
              }
                     
              return NULL;
       }

       disp = disp_constructor(val TSRMLS_CC);
       generate_dispids(disp TSRMLS_CC);

       return (IDispatch*)disp;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI IDispatch* php_com_wrapper_export_as_sink ( zval *  val,
GUID *  sinkid,
HashTable *id_to_name  TSRMLS_DC 
)

Definition at line 589 of file com_wrapper.c.

{
       php_dispatchex *disp = disp_constructor(val TSRMLS_CC);
       HashPosition pos;
       char *name = NULL;
       zval *tmp, **ntmp;
       int namelen;
       int keytype;
       ulong pid;

       disp->dispid_to_name = id_to_name;

       memcpy(&disp->sinkid, sinkid, sizeof(disp->sinkid));
       
       /* build up the reverse mapping */
       ALLOC_HASHTABLE(disp->name_to_dispid);
       zend_hash_init(disp->name_to_dispid, 0, NULL, ZVAL_PTR_DTOR, 0);
       
       zend_hash_internal_pointer_reset_ex(id_to_name, &pos);
       while (HASH_KEY_NON_EXISTANT != (keytype =
                            zend_hash_get_current_key_ex(id_to_name, &name, &namelen, &pid, 0, &pos))) {

              if (keytype == HASH_KEY_IS_LONG) {

                     zend_hash_get_current_data_ex(id_to_name, (void**)&ntmp, &pos);
                     
                     MAKE_STD_ZVAL(tmp);
                     ZVAL_LONG(tmp, pid);
                     zend_hash_update(disp->name_to_dispid, Z_STRVAL_PP(ntmp),
                            Z_STRLEN_PP(ntmp)+1, (void*)&tmp, sizeof(zval *), NULL);
              }

              zend_hash_move_forward_ex(id_to_name, &pos);
       }

       return (IDispatch*)disp;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 63 of file com_wrapper.c.

{
       le_dispatch = zend_register_list_destructors_ex(dispatch_dtor,
              NULL, "com_dotnet_dispatch_wrapper", module_number);
       return le_dispatch;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void trace ( char *  fmt,
  ... 
) [inline, static]

Definition at line 72 of file com_wrapper.c.

{
       va_list ap;
       char buf[4096];

       snprintf(buf, sizeof(buf), "T=%08x ", GetCurrentThreadId());
       OutputDebugString(buf);
       
       va_start(ap, fmt);
       vsnprintf(buf, sizeof(buf), fmt, ap);

       OutputDebugString(buf);
       
       va_end(ap);
}

Here is the caller graph for this function:


Variable Documentation

struct IDispatchExVtbl [static]
int le_dispatch [static]

Definition at line 53 of file com_wrapper.c.