7

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.

Roman R.
  • 68,205
  • 6
  • 94
  • 158
CodeCat
  • 161
  • 1
  • 5
  • 8
  • possible duplicate of [How to retrieve the Interface ID of a COM class so that it can be passed to CoCreateInstance?](http://stackoverflow.com/questions/2313432/how-to-retrieve-the-interface-id-of-a-com-class-so-that-it-can-be-passed-to-cocr) – Roger Rowland Sep 03 '13 at 10:59
  • What is the exact value of hr1? – StuartRedmann Sep 04 '13 at 10:46

3 Answers3

7

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.

Roman R.
  • 68,205
  • 6
  • 94
  • 158
  • The com class isn't created by me and I can't see the code and IID identifier.Then I use IID_IDispatch ,but the program can't work(It can be compiled but failed in running). – CodeCat Sep 03 '13 at 11:17
  • 1
    If the COM library/component is not yours, you need additional information from the vendor, or you might possibly looks up the identifiers via type library (see [COM/OLE Viewer tool](http://msdn.microsoft.com/en-us/library/d0kh9f4c.aspx)). – Roman R. Sep 03 '13 at 11:25
  • I can call it in VB: set se = createobject("se.mysoft"). I don't know how to call it in c++ – CodeCat Sep 03 '13 at 11:39
  • 1
    _"Some COM classes implement well known interface"_ Well then, might be worth pointing out that ***all*** COM classes implement _at least_ `IUnknown` :) – sehe Sep 03 '13 at 12:26
  • I found the implement, but I still failed. – CodeCat Sep 03 '13 at 12:37
  • I found a header file of the COM component. I am trying to include and compile it. But here are so many errors. I am repairing it. – CodeCat Sep 03 '13 at 13:42
  • My compiler is MINGW, I can't use '__uuidof'. – CodeCat Sep 03 '13 at 14:08
  • `IID_Isesoft` is another option - depends on the header you use, it might/should be defined there this way. – Roman R. Sep 03 '13 at 14:15
  • IID_Isesoft was not declared. The header I use only include one class Idmsoft. – CodeCat Sep 03 '13 at 14:27
2

I suppose that your CLSID is correct, since hr has a value of 0. From the extract of your idl.file, I conclude that the interface‘s ID is {F3F54BC2-D6D1-4A85-B943-16287ECEA64C} and its name Isesoft. Your present code provides a pointer to IDispatch and hr1 should be 0 if hr is 0. To get a raw COM pointer to this interface you must pass the CLSID and the IID as well as the address of a pointer to Isesoft.

Now change your code:

CLSID clsid;
RIID iid;
IseSoft* pIceSoft; 
HRESULT hr = CLSIDFromProgID(OLESTR("se.mysoft"),&clsid);
HRESULT hr2 = IIDFromString(OLESTR("{F3F54BC2-D6D1-4A85-B943-16287ECEA64C}"), &iid);
HRESULT hr3 = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, (void **)&pIseSoft);

A final remark: Since your hr1 returns a fail which it shouldn't, I presume that something is wrong with the CLSID. You can find the correct CLSID in the idl file from where you got the IID oft he interface.

Nevertheless, with your code all you would get is a useless IDispatch pointer, because that is what you are asking for.

1

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);
Michael M.
  • 2,556
  • 1
  • 16
  • 26
  • Where can i find the interface? I don't have the COM component's source code. I can call it in VB: set se = createobject("se.mysoft") I don't know how to call it in c++. – CodeCat Sep 03 '13 at 11:29
  • @CodeCat have you tried importing the .dll ? That generates header files that you can include to access the COM object. Just write #import "yourdll.dll" in your cpp file (and make sure you got a path to it) – AndersK Sep 03 '13 at 13:04
  • when I imported dll file and compiled it , the compiler show many error. – CodeCat Sep 03 '13 at 13:37