我自己写了一个简单的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的初学者, 请各位帮帮忙, 谢谢了:)

解决方案 »

  1.   


    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;
        }
    };
      

  2.   

    http://www.codeproject.com/KB/COM/com_in_c2.aspx