我自己写了一个简单的COM组件, 没有使用MFC, 也没有使用ATL, 只有两个方法, 一个属性, IDL文件如下:import "oaidl.idl";
import "ocidl.idl";[
object,
uuid(30278898-6712-4bdf-985F-A1EED2A1C4E9),
pointer_default(unique),
dual
]
interface IDeviceControl : IDispatch
{
[id(1)]
HRESULT Startup([in] BSTR bstrClass);
[id(2)]
HRESULT Stop([in] BSTR bstrClass);
[propget, id(3)]
HRESULT UsbClass([out, retval] VARIANT_BOOL* lpbStatus);
[propput, id(3)]
HRESULT UsbClass([in] VARIANT_BOOL bStatus);
};[
version(1.0),
uuid(165A29C3-986B-48ae-BF92-D676DAD77900)
]
library DeviceControl
{
importlib("stdole2.tlb");
importlib("stdole32.tlb"); [
uuid(B967383B-8002-405a-BB73-5CDC75E0AA3D)
]
coclass DeviceControl
{
[default] interface IDeviceControl;
}
};
在IDispatch接口的GetIdsOfNames()与Invoke()中我是使用的类型库ITypeInfo接口的,代码如下:STDMETHODIMP CDeviceControl::GetIDsOfNames(
REFIID interfaceId,
LPOLESTR* lpposzName,
UINT nName,
LCID intoLcid,
DISPID* lpDispId)
{
OutputDebugString(L"CDeviceControl::GetIDsOfNames..."); ITypeInfo* pTypeInfo = NULL;
HRESULT hResult = GetTypeInfo(0, GetUserDefaultLCID(), &pTypeInfo);
if (FAILED(hResult))
{
OutputDebugString(L"GetTypeInfo is failed...");
return E_FAIL;
} hResult = pTypeInfo->GetIDsOfNames(lpposzName, nName, lpDispId);
if (FAILED(hResult))
{
OutputDebugString(L"GetIDsOfNames is failed...");
return E_FAIL;
} pTypeInfo->Release(); return S_OK;
}STDMETHODIMP CDeviceControl::Invoke(
DISPID dispId,
REFIID interfaceId,
LCID infoLcid,
WORD wFlag,
DISPPARAMS* lpDispParams,
VARIANT* lpResultVar,
EXCEPINFO* lpExpInfo,
UINT* lpArgErr)
{
ITypeInfo* pTypeInfo = NULL;
HRESULT hResult = GetTypeInfo(0, GetUserDefaultLCID(), &pTypeInfo);
if (FAILED(hResult))
{
OutputDebugString(L"GetTypeInfo is failed...");
return E_FAIL;
} hResult = pTypeInfo->Invoke(
static_cast<IDeviceControl*>(this),
dispId,
wFlag,
lpDispParams,
lpResultVar,
lpExpInfo,
lpArgErr);
if (FAILED(hResult))
{
OutputDebugString(L"GetIDsOfNames is failed...");
return E_FAIL;
} pTypeInfo->Release(); return S_OK;
}
STDMETHODIMP CDeviceControl::Startup(BSTR bstrClass)
{
wcout << L"Startup " << bstrClass << endl;
return S_OK;
}STDMETHODIMP CDeviceControl::Stop(BSTR bstrClass)
{
wcout << L"Stop " << bstrClass << endl;
return S_OK;
}STDMETHODIMP CDeviceControl::get_UsbClass(VARIANT_BOOL* lpbStatus)
{
*lpbStatus = TRUE;
wcout << L"get_UsbClass status..." << endl;
return S_OK;
}STDMETHODIMP CDeviceControl::put_UsbClass(VARIANT_BOOL bStatus)
{
if (bStatus)
{
wcout << L"put_UsbClass status startup..." << endl;
}
else
{
wcout << L"put_UsbClass status stop..." << endl;
}
return S_OK;
}
客户端代码如下:int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hResult = CoInitialize(NULL);
if (FAILED(hResult))
{
wcout << L"CoInitialize is failed..." << endl;
return 1;
} CComPtr<IDispatch> spDispatch = NULL;
hResult = CoCreateInstance(
CLSID_DeviceControl,
NULL,
CLSCTX_INPROC_SERVER,
IID_IDeviceControl,
reinterpret_cast<PVOID*>(&spDispatch));
if (FAILED(hResult))
{
wcout << L"CoCreateInstance is failed..." << endl;
return 1;
} DISPID startupDispId = 0;
LPOLESTR poszStartup[1] = {L"Startup"};
hResult = spDispatch->GetIDsOfNames(
IID_NULL,
poszStartup,
1,
GetUserDefaultLCID(),
&startupDispId);
if (FAILED(hResult))
{
wcout << L"GetIDsOfNames is failed..." << endl;
return 1;
}
cout << startupDispId << endl; DISPID stopDispId = 0;
LPOLESTR poszStop[1] = {L"Stop"};
hResult = spDispatch->GetIDsOfNames(
IID_NULL,
poszStop,
1,
GetUserDefaultLCID(),
&stopDispId);
if (FAILED(hResult))
{
wcout << L"GetIDsOfNames is failed..." << endl;
return 1;
}
cout << stopDispId << endl; DISPPARAMS dispParams = {0};
dispParams.cArgs = 1;
dispParams.rgvarg = new VARIANT[dispParams.cArgs];
if (NULL == dispParams.rgvarg)
{
wcout << L"new VARIANT is failed..." << endl;
return 1;
}
VariantInit(&dispParams.rgvarg[0]);
dispParams.rgvarg[0].vt = VT_BSTR;
dispParams.rgvarg[0].bstrVal = L"USB"; UINT nArgErr = 0; hResult = spDispatch->Invoke(
startupDispId,
IID_NULL,
GetUserDefaultLCID(),
DISPATCH_METHOD,
&dispParams,
NULL,
NULL,
&nArgErr);
if (FAILED(hResult))
{
wcout << L"Invoke is failed..." << endl;
return 1;
} delete dispParams.rgvarg;
dispParams.rgvarg = NULL; dispParams.cArgs = 1;
dispParams.rgvarg = new VARIANT[dispParams.cArgs];
if (NULL == dispParams.rgvarg)
{
wcout << L"new VARIANT is failed..." << endl;
return 1;
}
VariantInit(&dispParams.rgvarg[0]);
dispParams.rgvarg[0].vt = VT_BSTR;
dispParams.rgvarg[0].bstrVal = L"Stop";
hResult = spDispatch->Invoke(
stopDispId,
IID_NULL,
GetUserDefaultLCID(),
DISPATCH_METHOD,
&dispParams,
NULL,
NULL,
&nArgErr);
if (FAILED(hResult))
{
wcout << L"Invoke UsbClass is failed..." << endl;
return 1;
} delete dispParams.rgvarg;
dispParams.rgvarg = NULL; dispParams.cArgs = 1;
dispParams.rgvarg = new VARIANTARG[1];
dispParams.rgvarg[0].vt = VT_BOOL;
dispParams.rgvarg[0].boolVal = FALSE;
hResult = spDispatch->Invoke(
3,
IID_NULL,
GetUserDefaultLCID(),
DISPATCH_PROPERTYPUT,
&dispParams,
NULL,
NULL,
&nArgErr);
if (FAILED(hResult))
{
wcout << L"Invoke put_UsbClass is failed..." << endl;
return 1;
} delete dispParams.rgvarg;
dispParams.rgvarg = NULL;
spDispatch.Release(); CoUninitialize(); return 0;
}
前两个方发的调用是没有问题的, 可是对于属性的调用却步行, ITypeInfo->Invoke(...)的调用返回的hResult为"找不参数", 我调试过, 我在调用时, 传入的参数是没有问题的, 只是不知道为什么ITypeInfo->Invoke(...)会出错, 我是个COM的初学者, 请各位帮帮忙, 谢谢了:)
import "ocidl.idl";[
object,
uuid(30278898-6712-4bdf-985F-A1EED2A1C4E9),
pointer_default(unique),
dual
]
interface IDeviceControl : IDispatch
{
[id(1)]
HRESULT Startup([in] BSTR bstrClass);
[id(2)]
HRESULT Stop([in] BSTR bstrClass);
[propget, id(3)]
HRESULT UsbClass([out, retval] VARIANT_BOOL* lpbStatus);
[propput, id(3)]
HRESULT UsbClass([in] VARIANT_BOOL bStatus);
};[
version(1.0),
uuid(165A29C3-986B-48ae-BF92-D676DAD77900)
]
library DeviceControl
{
importlib("stdole2.tlb");
importlib("stdole32.tlb"); [
uuid(B967383B-8002-405a-BB73-5CDC75E0AA3D)
]
coclass DeviceControl
{
[default] interface IDeviceControl;
}
};
在IDispatch接口的GetIdsOfNames()与Invoke()中我是使用的类型库ITypeInfo接口的,代码如下:STDMETHODIMP CDeviceControl::GetIDsOfNames(
REFIID interfaceId,
LPOLESTR* lpposzName,
UINT nName,
LCID intoLcid,
DISPID* lpDispId)
{
OutputDebugString(L"CDeviceControl::GetIDsOfNames..."); ITypeInfo* pTypeInfo = NULL;
HRESULT hResult = GetTypeInfo(0, GetUserDefaultLCID(), &pTypeInfo);
if (FAILED(hResult))
{
OutputDebugString(L"GetTypeInfo is failed...");
return E_FAIL;
} hResult = pTypeInfo->GetIDsOfNames(lpposzName, nName, lpDispId);
if (FAILED(hResult))
{
OutputDebugString(L"GetIDsOfNames is failed...");
return E_FAIL;
} pTypeInfo->Release(); return S_OK;
}STDMETHODIMP CDeviceControl::Invoke(
DISPID dispId,
REFIID interfaceId,
LCID infoLcid,
WORD wFlag,
DISPPARAMS* lpDispParams,
VARIANT* lpResultVar,
EXCEPINFO* lpExpInfo,
UINT* lpArgErr)
{
ITypeInfo* pTypeInfo = NULL;
HRESULT hResult = GetTypeInfo(0, GetUserDefaultLCID(), &pTypeInfo);
if (FAILED(hResult))
{
OutputDebugString(L"GetTypeInfo is failed...");
return E_FAIL;
} hResult = pTypeInfo->Invoke(
static_cast<IDeviceControl*>(this),
dispId,
wFlag,
lpDispParams,
lpResultVar,
lpExpInfo,
lpArgErr);
if (FAILED(hResult))
{
OutputDebugString(L"GetIDsOfNames is failed...");
return E_FAIL;
} pTypeInfo->Release(); return S_OK;
}
STDMETHODIMP CDeviceControl::Startup(BSTR bstrClass)
{
wcout << L"Startup " << bstrClass << endl;
return S_OK;
}STDMETHODIMP CDeviceControl::Stop(BSTR bstrClass)
{
wcout << L"Stop " << bstrClass << endl;
return S_OK;
}STDMETHODIMP CDeviceControl::get_UsbClass(VARIANT_BOOL* lpbStatus)
{
*lpbStatus = TRUE;
wcout << L"get_UsbClass status..." << endl;
return S_OK;
}STDMETHODIMP CDeviceControl::put_UsbClass(VARIANT_BOOL bStatus)
{
if (bStatus)
{
wcout << L"put_UsbClass status startup..." << endl;
}
else
{
wcout << L"put_UsbClass status stop..." << endl;
}
return S_OK;
}
客户端代码如下:int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hResult = CoInitialize(NULL);
if (FAILED(hResult))
{
wcout << L"CoInitialize is failed..." << endl;
return 1;
} CComPtr<IDispatch> spDispatch = NULL;
hResult = CoCreateInstance(
CLSID_DeviceControl,
NULL,
CLSCTX_INPROC_SERVER,
IID_IDeviceControl,
reinterpret_cast<PVOID*>(&spDispatch));
if (FAILED(hResult))
{
wcout << L"CoCreateInstance is failed..." << endl;
return 1;
} DISPID startupDispId = 0;
LPOLESTR poszStartup[1] = {L"Startup"};
hResult = spDispatch->GetIDsOfNames(
IID_NULL,
poszStartup,
1,
GetUserDefaultLCID(),
&startupDispId);
if (FAILED(hResult))
{
wcout << L"GetIDsOfNames is failed..." << endl;
return 1;
}
cout << startupDispId << endl; DISPID stopDispId = 0;
LPOLESTR poszStop[1] = {L"Stop"};
hResult = spDispatch->GetIDsOfNames(
IID_NULL,
poszStop,
1,
GetUserDefaultLCID(),
&stopDispId);
if (FAILED(hResult))
{
wcout << L"GetIDsOfNames is failed..." << endl;
return 1;
}
cout << stopDispId << endl; DISPPARAMS dispParams = {0};
dispParams.cArgs = 1;
dispParams.rgvarg = new VARIANT[dispParams.cArgs];
if (NULL == dispParams.rgvarg)
{
wcout << L"new VARIANT is failed..." << endl;
return 1;
}
VariantInit(&dispParams.rgvarg[0]);
dispParams.rgvarg[0].vt = VT_BSTR;
dispParams.rgvarg[0].bstrVal = L"USB"; UINT nArgErr = 0; hResult = spDispatch->Invoke(
startupDispId,
IID_NULL,
GetUserDefaultLCID(),
DISPATCH_METHOD,
&dispParams,
NULL,
NULL,
&nArgErr);
if (FAILED(hResult))
{
wcout << L"Invoke is failed..." << endl;
return 1;
} delete dispParams.rgvarg;
dispParams.rgvarg = NULL; dispParams.cArgs = 1;
dispParams.rgvarg = new VARIANT[dispParams.cArgs];
if (NULL == dispParams.rgvarg)
{
wcout << L"new VARIANT is failed..." << endl;
return 1;
}
VariantInit(&dispParams.rgvarg[0]);
dispParams.rgvarg[0].vt = VT_BSTR;
dispParams.rgvarg[0].bstrVal = L"Stop";
hResult = spDispatch->Invoke(
stopDispId,
IID_NULL,
GetUserDefaultLCID(),
DISPATCH_METHOD,
&dispParams,
NULL,
NULL,
&nArgErr);
if (FAILED(hResult))
{
wcout << L"Invoke UsbClass is failed..." << endl;
return 1;
} delete dispParams.rgvarg;
dispParams.rgvarg = NULL; dispParams.cArgs = 1;
dispParams.rgvarg = new VARIANTARG[1];
dispParams.rgvarg[0].vt = VT_BOOL;
dispParams.rgvarg[0].boolVal = FALSE;
hResult = spDispatch->Invoke(
3,
IID_NULL,
GetUserDefaultLCID(),
DISPATCH_PROPERTYPUT,
&dispParams,
NULL,
NULL,
&nArgErr);
if (FAILED(hResult))
{
wcout << L"Invoke put_UsbClass is failed..." << endl;
return 1;
} delete dispParams.rgvarg;
dispParams.rgvarg = NULL;
spDispatch.Release(); CoUninitialize(); return 0;
}
前两个方发的调用是没有问题的, 可是对于属性的调用却步行, ITypeInfo->Invoke(...)的调用返回的hResult为"找不参数", 我调试过, 我在调用时, 传入的参数是没有问题的, 只是不知道为什么ITypeInfo->Invoke(...)会出错, 我是个COM的初学者, 请各位帮帮忙, 谢谢了:)
import "oaidl.idl";
import "ocidl.idl";[
object,
uuid(30278898-6712-4bdf-985F-A1EED2A1C4E9),
pointer_default(unique),
dual,
oleautomation
]
interface IDeviceControl : IDispatch
{
[id(1)]
HRESULT Startup([in] BSTR bstrClass);
[id(2)]
HRESULT Stop([in] BSTR bstrClass);
[propget, id(3)]
HRESULT UsbClass([out, retval] VARIANT_BOOL* lpbStatus);
[propput, id(3)]
HRESULT UsbClass([in] VARIANT_BOOL bStatus);
};[
version(1.0),
uuid(165A29C3-986B-48ae-BF92-D676DAD77900)
]
library DeviceControl
{
importlib("stdole2.tlb");
importlib("stdole32.tlb"); [
uuid(B967383B-8002-405a-BB73-5CDC75E0AA3D)
]
coclass DeviceControl
{
[default] interface IDeviceControl;
}
};