#pragma once
#include "unknwn.h"
class SCPIFactory :public IClassFactory
{
public:
SCPIFactory(void);
~SCPIFactory(void);
public:
//IUnknow Method
STDMETHODIMP QueryInterface(REFIID,void**);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
//IClassFactory Method
STDMETHODIMP CreateInstance(IUnknown * ,REFIID ,void **);
STDMETHODIMP LockServer(BOOL fLock);
private:
LONG m_cRef;
};
import "oaidl.idl";import "ocidl.idl";[uuid(011E50FF-873E-4FB2-86D5-296BFFCB47C4),object, dual,//这个标识说明定义的是双接口pointer_default(unique)]interface ISCPI : IDispatch//必须从IDispatch接口派生{[id(1)]HRESULT add([in]int a, [in]int b, [out]int* c);};[uuid(681B4072-519F-43B2-A356-055CD5B9FFC1),version(1.0),]library SCPILib{importlib("stdole32.tlb");importlib("stdole2.tlb");[uuid(050779DB-3DF0-49C4-9CCF-C92BD363DB82)]coclass SCPIImp//com类{[default] interface ISCPI;};};
SCPIX.idl
SCPIImp.h
#pragma once
#include "SCPI_h.h"
class SCPIImp :public ISCPI
{
public:
SCPIImp(void);
~SCPIImp(void);
public:
//IUnknown接口
STDMETHOD(QueryInterface)(REFIID riid, void **ppv);//接口查询
STDMETHOD_(ULONG, AddRef)();//增加一个引用
STDMETHOD_(ULONG, Release)();//减少一个引用
// IDispatch
STDMETHOD(GetTypeInfoCount)(UINT * pit);
STDMETHOD(GetTypeInfo)(UINT it,LCID lcid,ITypeInfo **ppti);
STDMETHOD(GetIDsOfNames)(REFIID riid, OLECHAR ** pNames, UINT nNames, LCID lcid, DISPID * pdispids);
STDMETHOD(Invoke)(DISPID id, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pd, VARIANT * pVarResult, EXCEPINFO * pe, UINT *pu);
//ISCPI
STDMETHOD(add)(int a, int b, int *c);
private:
ULONG m_cRef; //引用计数
};
SCPImp.cpp
#include "SCPIImp.h"
SCPIImp::SCPIImp(void)
{
m_cRef = 0;
}
SCPIImp::~SCPIImp(void)
{
}
//IUnknown接口
STDMETHODIMP SCPIImp::QueryInterface(REFIID riid, void **ppv)
{
if(riid == IID_ISCPI)
*ppv = static_cast<ISCPI *>(this);
else if(riid == IID_IUnknown)
*ppv = static_cast<ISCPI *>(this);
else if(riid == IID_IDispatch)
*ppv = reinterpret_cast<IDispatch *>(this);
else {
*ppv = 0;
return E_NOINTERFACE;
}
reinterpret_cast<IUnknown *>(*ppv)->AddRef();
return S_OK;
}
STDMETHODIMP_(ULONG) SCPIImp::AddRef()
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) SCPIImp::Release()
{
ULONG res = --m_cRef;
if(res == 0)
delete this;
return res;
}
// IDispatch
STDMETHODIMP SCPIImp::Invoke(DISPID id, REFIID riid, LCID lcid,
WORD wFlags, DISPPARAMS *pd,
VARIANT * pVarResult, EXCEPINFO * pe, UINT *pu)
{
if(riid == IID_ISCPI)
{
if(1 == id)
return add(pd->rgvarg->iVal, pd->rgvarg->iVal , &pVarResult->intVal);
else
return E_FAIL;
}
else
return E_NOINTERFACE;
}
STDMETHODIMP SCPIImp::GetIDsOfNames(REFIID riid, OLECHAR ** pNames,
UINT nNames, LCID lcid, DISPID * pdispids)
{
return E_NOTIMPL;
}
STDMETHODIMP SCPIImp::GetTypeInfo(UINT it,LCID lcid,ITypeInfo **ppti)
{
return E_NOTIMPL;
}
STDMETHODIMP SCPIImp::GetTypeInfoCount(UINT * pit)
{
return E_NOTIMPL;
}
STDMETHODIMP SCPIImp::add(int a, int b, int *c)
{
*c = a + b;
return S_OK;
}
#pragma once
#include "unknwn.h"
#include "unknwn.h"
class SCPIFactory :public IClassFactory
{
public:
SCPIFactory(void);
~SCPIFactory(void);
public:
{
public:
SCPIFactory(void);
~SCPIFactory(void);
public:
//IUnknow Method
STDMETHODIMP QueryInterface(REFIID,void**);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
STDMETHODIMP QueryInterface(REFIID,void**);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
//IClassFactory Method
STDMETHODIMP CreateInstance(IUnknown * ,REFIID ,void **);
STDMETHODIMP LockServer(BOOL fLock);
STDMETHODIMP CreateInstance(IUnknown * ,REFIID ,void **);
STDMETHODIMP LockServer(BOOL fLock);
private:
LONG m_cRef;
};
LONG m_cRef;
};
#include "SCPIFactory.h"
#include "SCPIImp.h"
#include "SCPI_h.h"
#include "SCPIImp.h"
#include "SCPI_h.h"
extern LONG g_cObjectAndLocks;
SCPIFactory::SCPIFactory(void)
{
m_cRef = 0;
}
{
m_cRef = 0;
}
SCPIFactory::~SCPIFactory(void)
{
}
{
}
STDMETHODIMP_(ULONG) SCPIFactory::AddRef(void)
{
return InterlockedIncrement(&m_cRef);
}
{
return InterlockedIncrement(&m_cRef);
}
STDMETHODIMP_(ULONG) SCPIFactory::Release(void)
{
return ::InterlockedDecrement(&m_cRef);
}
{
return ::InterlockedDecrement(&m_cRef);
}
STDMETHODIMP SCPIFactory::QueryInterface(REFIID riid,void ** ppv)
{
*ppv = NULL;
if(riid == IID_IUnknown || riid == IID_IClassFactory || riid == IID_IDispatch)
{
*ppv = static_cast<IClassFactory *>(this);
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
return S_OK;
}
else
return (*ppv=0),E_NOINTERFACE;
}
{
*ppv = NULL;
if(riid == IID_IUnknown || riid == IID_IClassFactory || riid == IID_IDispatch)
{
*ppv = static_cast<IClassFactory *>(this);
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
return S_OK;
}
else
return (*ppv=0),E_NOINTERFACE;
}
STDMETHODIMP SCPIFactory::CreateInstance(IUnknown * pUnkOuter,REFIID riid,void ** ppv)
{
*ppv=NULL;
{
*ppv=NULL;
if(pUnkOuter != NULL)
return CLASS_E_NOAGGREGATION;
return CLASS_E_NOAGGREGATION;
SCPIImp * pSCPIImp = new SCPIImp();
if(pSCPIImp == NULL)
return E_OUTOFMEMORY;
if(pSCPIImp == NULL)
return E_OUTOFMEMORY;
HRESULT hr = pSCPIImp->QueryInterface(riid,ppv);
if(FAILED(hr))
delete pSCPIImp;
delete pSCPIImp;
return hr;
}
}
STDMETHODIMP SCPIFactory::LockServer(BOOL fLock)
{
if(fLock)
::InterlockedIncrement(&g_cObjectAndLocks);
else
::InterlockedDecrement(&g_cObjectAndLocks);
return NOERROR;
{
if(fLock)
::InterlockedIncrement(&g_cObjectAndLocks);
else
::InterlockedDecrement(&g_cObjectAndLocks);
return NOERROR;
}
#include "SCPIImp.h"
#include "SCPIFactory.h"
#include "SCPI_h.h"
#include "SCPI_i.c"
LONG g_cObjectAndLocks=0;
const char * g_RegTable[][3]={
{"CLSID//{050779DB-3DF0-49C4-9CCF-C92BD363DB82}",
0,
"SCPIX"},
{"CLSID//{050779DB-3DF0-49C4-9CCF-C92BD363DB82}//InprocServer32",
0,
(const char * )-1},
{"CLSID//{050779DB-3DF0-49C4-9CCF-C92BD363DB82}//ProgID",
0,
"SCPIX.2"},
{"SCPIX.SCPI.2",
0,
"SCPI"},
{"SCPIX.SCPI.2//CLSID",
0,
"{050779DB-3DF0-49C4-9CCF-C92BD363DB82}"},
};
HINSTANCE g_hinstDll;
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
g_hinstDll = (HINSTANCE)hModule;
return TRUE;
}
STDAPI DllUnregisterServer(void)//从注册表中注销
{
HRESULT hr = S_OK;
char szFileName [MAX_PATH];
::GetModuleFileName(g_hinstDll,szFileName,MAX_PATH);
int nEntries = sizeof(g_RegTable) / sizeof(*g_RegTable);
for(int i = 0; SUCCEEDED(hr) && i < nEntries; i ++)
{
const char * pszKeyName = g_RegTable[i][0];
long err = ::RegDeleteKey(HKEY_CLASSES_ROOT, pszKeyName);
if( err != ERROR_SUCCESS)
hr = S_FALSE;
}
return hr;
}
STDAPI DllRegisterServer(void)//注册服务器
{
HRESULT hr = S_OK;
char szFileName [MAX_PATH];
::GetModuleFileName(g_hinstDll, szFileName, MAX_PATH);
int nEntries = sizeof(g_RegTable) / sizeof(*g_RegTable);
for(int i = 0 ; SUCCEEDED(hr) && i < nEntries; i ++)
{
const char * pszKeyName = g_RegTable[i][0];
const char * pszValueName = g_RegTable[i][1];
const char * pszValue = g_RegTable[i][2];
if(pszValue == (const char *) - 1)
{
pszValue = szFileName;
}
HKEY hkey;
long err = ::RegCreateKey(HKEY_CLASSES_ROOT, pszKeyName, &hkey);
if(err == ERROR_SUCCESS)
{
err = ::RegSetValueEx( hkey,
pszValueName,
0,
REG_SZ,
( const BYTE*)pszValue,
( strlen(pszValue)+1 ) );
::RegCloseKey(hkey);
}
if( err != ERROR_SUCCESS)
{
::DllUnregisterServer();
hr = E_FAIL;
}
}
return hr;
}
STDAPI DllGetClassObject(REFCLSID rclsid ,REFIID riid,void **ppv)
{
if(rclsid == CLSID_SCPIImp)
{
SCPIFactory *pFactory = new SCPIFactory;
if(pFactory == NULL)
return E_OUTOFMEMORY;
HRESULT hr = pFactory->QueryInterface(riid, ppv);
return hr;
}
return CLASS_E_CLASSNOTAVAILABLE;
}
STDAPI DllCanUnloadNow(void)
{
return ( g_cObjectAndLocks == 0 )
? S_OK : E_FAIL;
}
#include "SCPIFactory.h"
#include "SCPIImp.h"
#include "SCPI_h.h"
extern LONG g_cObjectAndLocks;
SCPIFactory::SCPIFactory(void)
{
m_cRef = 0;
}
SCPIFactory::~SCPIFactory(void)
{
}
STDMETHODIMP_(ULONG) SCPIFactory::AddRef(void)
{
return InterlockedIncrement(&m_cRef);
}
STDMETHODIMP_(ULONG) SCPIFactory::Release(void)
{
return ::InterlockedDecrement(&m_cRef);
}
STDMETHODIMP SCPIFactory::QueryInterface(REFIID riid,void ** ppv)
{
*ppv = NULL;
if(riid == IID_IUnknown || riid == IID_IClassFactory || riid == IID_IDispatch)
{
*ppv = static_cast<IClassFactory *>(this);
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
return S_OK;
}
else
return (*ppv=0),E_NOINTERFACE;
}
STDMETHODIMP SCPIFactory::CreateInstance(IUnknown * pUnkOuter,REFIID riid,void ** ppv)
{
*ppv=NULL;
if(pUnkOuter != NULL)
return CLASS_E_NOAGGREGATION;
SCPIImp * pSCPIImp = new SCPIImp();
if(pSCPIImp == NULL)
return E_OUTOFMEMORY;
HRESULT hr = pSCPIImp->QueryInterface(riid,ppv);
if(FAILED(hr))
delete pSCPIImp;
return hr;
}
STDMETHODIMP SCPIFactory::LockServer(BOOL fLock)
{
if(fLock)
::InterlockedIncrement(&g_cObjectAndLocks);
else
::InterlockedDecrement(&g_cObjectAndLocks);
return NOERROR;
}