问题
I had registered a COM component.And I want to call it.
CLSID clsid;
RIID iid;
HRESULT hr = CLSIDFromProgID(OLESTR("se.mysoft"),&clsid);
LPVOID *pRet;
HRESULT hr1 = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, pRet);
I can get the clsid successful, but where can I get the iid ?
I used OLE VIEWER find interface:
[
odl,
uuid(F3F54BC2-D6D1-4A85-B943-16287ECEA64C),
helpstring("Isesoft Interface"),
dual,
oleautomation
]
interface Isesoft : IDispatch {
Then I changed my code:
CLSID clsid;
RIID iid;
IDispatch* pDispatch;
HRESULT hr = CLSIDFromProgID(OLESTR("se.mysoft"),&clsid);
HRESULT hr1 = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IDispatch,(void **)&pDispatch);
But hr1 returned failed.
回答1:
Your COM class implements some interfaces and each interface has its IID
identifier. So you need to get it from your COM component implementation. It's your code and you are expected to provide the identifier which exactly specifies what interface you are requesting.
Some COM classes implement well known interface, esp. IDispatch
, the identifier for which is IID_IDispatch
, or __uuidof(IDispatch)
.
UPD. Since you found that the interface of interest is Isesoft
, your code will be:
CLSID clsid;
RIID iid;
IDispatch* pDispatch;
HRESULT nResult1 = CLSIDFromProgID(OLESTR("se.mysoft"), &clsid);
HRESULT nResult2 = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER,
IID_Isesoft, (void **) &pDispatch);
To get Isesoft
and IID_Isesoft
, __uuidof(Isesoft)
available to C++ code, you will need to import the definitions, which is typically either of then two:
- additional vendor SDK includes e.g.
#include "isesoft\sdk.h"
- or #import "libid:..." with type library identifier (namespace and other attributes apply)
When you have HRESULT
codes indicating failures, make sure to post the values.
回答2:
You should know the interface you want on your object, let call it IMyInterface
.
IMyInterface* pItf = NULL;
hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IMyInterface, (void**)&pItf);
回答3:
It's not enough to find the IID of the interface, you also need the LIBID of the typelib as Roman pointed out. Since you know the IID of the interface, open regedit and input Computer\HKEY_CLSSES_ROOT\Interface{F3F54BC2-D6D1-4A85-B943-16287ECEA64C}\TypeLib, use backslashes. You get the LIBID, assume the value is {6F88B941-D87E-4B5E-BAE2-01cc21900dd8}. In your program add the statement #import "libid:6F88B941-D87E-4B5E-BAE2-01cc21900dd8"
, no curly braces here. Build the project, then, usually in the x64\Release or x64\Debug folder, you will find the file se.tlh, named after the server part of the ProgID. This file contains the declarations and IIDs of all exposed interfaces, hopefully the interface IceSoft too (funny name, by the way). Did you also search in regedit or oleview for an interface Imysoft, because that would be the common name of the default dispatch interface of a CoClass with the ProgID se.mysoft.
Now change your code:
#import "libid:6F88B941-D87E-4B5E-BAE2-01cc21900dd8"//replace correct LIBID
… later:
CLSID clsid;
RIID iid;
CComPtr<IceSoft> pIceSoft; // no *
HRESULT hr = CLSIDFromProgID(OLESTR("se.mysoft"),&clsid);
hr = IIDFromString(OLESTR("{F3F54BC2-D6D1-4A85-B943-16287ECEA64C}"), &iid);
HRESULT hr1 = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, (void **)&pIceSoft);
A final remark: Since your hr1
returns a fail which it shouldn't, I presume that something is wrong with the CLSID. The error code for hr1
would be 800401F3 (CO_E_CLASSSTRING: Invalid class string). Get the value from the CLSIDFromProgID(OLESTR("se.mysoft"),&clsid);
statement and in regedit input Computer\HKEY_CLASSES_ROOT\se.mysoft to compare it with value of the subkey CLSID.
Nevertheless, with your code all you would get is a useless IDispatch
pointer, because that is what you are asking for.
来源:https://stackoverflow.com/questions/18590499/how-to-use-cocreateinstance-to-get-a-com-object