//a c file. #include it in the XS file static char szWINOLE[] = "Win32::OLE"; static const DWORD WINOLE_MAGIC = 0x12344321; static const DWORD WINOLEENUM_MAGIC = 0x12344322; static const DWORD WINOLEVARIANT_MAGIC = 0x12344323; static const DWORD WINOLETYPELIB_MAGIC = 0x12344324; static const DWORD WINOLETYPEINFO_MAGIC = 0x12344325; #define COINIT_OLEINITIALIZE -1 #define COINIT_NO_INITIALIZE -2 typedef HRESULT (STDAPICALLTYPE FNCOINITIALIZEEX)(LPVOID, DWORD); typedef void (STDAPICALLTYPE FNCOUNINITIALIZE)(void); typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX) (REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*); typedef HWND (WINAPI FNHTMLHELP)(HWND hwndCaller, LPCSTR pszFile, UINT uCommand, DWORD dwData); typedef struct _tagOBJECTHEADER OBJECTHEADER; /* per interpreter variables */ typedef struct { CRITICAL_SECTION CriticalSection; OBJECTHEADER *pObj; BOOL bInitialized; HV *hv_unique; /* DCOM function addresses are resolved dynamically */ HINSTANCE hOLE32; FNCOINITIALIZEEX *pfnCoInitializeEx; FNCOUNINITIALIZE *pfnCoUninitialize; FNCOCREATEINSTANCEEX *pfnCoCreateInstanceEx; /* HTML Help Control loaded dynamically */ HINSTANCE hHHCTRL; FNHTMLHELP *pfnHtmlHelp; } PERINTERP; #ifdef PERL_IMPLICIT_CONTEXT # define dPERINTERP \ SV **pinterp = hv_fetch(PL_modglobal, MY_VERSION, \ sizeof(MY_VERSION)-1, FALSE); \ if (!pinterp || !*pinterp || !SvIOK(*pinterp)) \ warn(MY_VERSION ": Per-interpreter data not initialized"); \ PERINTERP *pInterp = INT2PTR(PERINTERP*, SvIV(*pinterp)) # define INTERP pInterp #else static PERINTERP Interp; # define dPERINTERP extern int errno # define INTERP (&Interp) #endif #define g_pObj (INTERP->pObj) #define g_bInitialized (INTERP->bInitialized) #define g_CriticalSection (INTERP->CriticalSection) #define g_hv_unique (INTERP->hv_unique) #define g_hOLE32 (INTERP->hOLE32) #define g_pfnCoInitializeEx (INTERP->pfnCoInitializeEx) #define g_pfnCoUninitialize (INTERP->pfnCoUninitialize) #define g_pfnCoCreateInstanceEx (INTERP->pfnCoCreateInstanceEx) #define g_hHHCTRL (INTERP->hHHCTRL) #define g_pfnHtmlHelp (INTERP->pfnHtmlHelp) /* common object header */ typedef struct _tagOBJECTHEADER { long lMagic; OBJECTHEADER *pNext; OBJECTHEADER *pPrevious; #ifdef PERL_IMPLICIT_CONTEXT PERINTERP *pInterp; #endif } OBJECTHEADER; #define OBJFLAG_DESTROYED 0x01 #define OBJFLAG_UNIQUE 0x02 typedef struct { OBJECTHEADER header; UV flags; IDispatch *pDispatch; ITypeInfo *pTypeInfo; IEnumVARIANT *pEnum; void *pEventSink; HV *self; HV *hashTable; SV *destroy; unsigned short cFuncs; unsigned short cVars; unsigned int PropIndex; } WINOLEOBJECT; void PLCOM(pTHX_ SV * sv){ WINOLEOBJECT *pObj; ISpVoice * SpVInterface; HRESULT hr; unsigned short vol; int dispatchpos = offsetof (WINOLEOBJECT, pDispatch); pObj = (WINOLEOBJECT*)(SvIV(sv)); if (pObj->header.lMagic != WINOLE_MAGIC || !(pObj->pDispatch)){ croak("PLCOM: GetOleObject() Not a %s object", szWINOLE); } hr = pObj->pDispatch->lpVtbl->QueryInterface(pObj->pDispatch, &IID_ISpVoice, (void **)&SpVInterface); printf("from c QI pdispath=%p lpvtbl=%p QI=%p\n", pObj->pDispatch, pObj->pDispatch->lpVtbl, pObj->pDispatch->lpVtbl->QueryInterface); if(hr != S_OK) croak("QueryInterface Failed"); hr = SpVInterface->lpVtbl->GetVolume(SpVInterface, &vol); if(hr != S_OK) croak("GetVolume Failed"); vol--; hr = SpVInterface->lpVtbl->SetVolume(SpVInterface, vol); if(hr != S_OK) croak("SetVolume Failed"); vol = 0; hr = SpVInterface->lpVtbl->GetVolume(SpVInterface, &vol); if(hr != S_OK) croak("GetVolume Failed"); printf("from c GV pdispath=%p lpvtbl=%p GV=%p\n", SpVInterface, SpVInterface->lpVtbl, SpVInterface->lpVtbl->GetVolume); printf("from c SV pdispath=%p lpvtbl=%p SV=%p\n", SpVInterface, SpVInterface->lpVtbl, SpVInterface->lpVtbl->SetVolume); hr = SpVInterface->lpVtbl->Release(SpVInterface); 0; } ##################################################################### //In the XS file void PLCOM(sv) SV * sv PPCODE: PLCOM(aTHX_ sv);