COM Connection Points: Problem to create an instance of an sink object.

Hi All,

I’m an absolutely newbie in the COM technology and I have a little tricky question. I hope there’s someone out there who can help me with my problem. I have an .idl / .h / .c file and I integrated them in my VisualStudio 2005 C++ project. After that I’ve searched on the MSDN Library how I can connect an COM Server from my project. I’ve found a little example (http://msdn.microsoft.com/en-us/magazine/cc163361.aspx) and tried to do it on the same way. I’ve created an Csink class and tried to create an instance of this sink object to pass to the server. But the problem now I get from my compiler is the following error message: „error C2259: 'CSink': cannot instantiate abstract class due to following members: 'HRESULT IUnknown::QueryInterface(const IID &,void **)' : is abstract“. Thiss Error message will come in the c++ file after the „pSink = new CSink();“ line. The thing I need is that I must call the „ OnShowMessageDlg “ and the „ OnConfigurationApply “ functions out of the .idl file in my main c++ function. I’ve put all the code here below in this entry. I hope that could help you to become an overview about my problem. Is the solution I’ve tried with the sink object correct or should I use another way to do this?

Please let me know if you need any other information.

Thanks for ANY help.

Juergen



*************************************************************************************************
.idl file
.
.
.
// TLib : // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
importlib("stdole2.tlb");

// Forward declare all types defined in this typelib
interface ITEST2;
dispinterface ITESTEvents;
.
.
.
[
uuid(6775FB91-B5BE-11D6-A996-0050BA24C7B9),
version(1.1),
helpstring("Event dispatch interface for TEST")
]
dispinterface ITESTEvents {
properties:
methods:
[id(0x00000001)]
void OnConfigurationApply([in, out] VARIANT_BOOL* pAccept);
[id(0x00000002)]
void OnShowMessageDlg(
[in] IMsgDlg* pIMsg,
[out, retval] VARIANT_BOOL* Result);
};
.
.
.
.
coclass TESTv2 {
[default] interface ITEST2;
[default, source] dispinterface ITESTEvents;
};
*************************************************************************************************


.h file
.
.
.
EXTERN_C const IID DIID_ITESTEvents;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("6775FB91-B5BE-11D6-A996-0050BA24C7B9")
ITESTEvents : public IDispatch
{
};

#else /* C style interface */
typedef struct ITESTEventsVtbl
{
BEGIN_INTERFACE

HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
ITESTEvents * This,
/* [in] */ REFIID riid,
/* [iid_is][out] */ void **ppvObject);

.
.
.
*************************************************************************************************

.c file
.
.
.
MIDL_DEFINE_GUID(IID, IID_ITEST2,0xF560F761,0x2948,0x11D7,0xA9,0xBF,0x00,0x50,0xBA,0x24,0xC7,0xB9);

MIDL_DEFINE_GUID(IID, DIID_ITESTEvents,0x6775FB91,0xB5BE,0x11D6,0xA9,0x96,0x00,0x50,0xBA,0x24,0xC7,0xB9);

MIDL_DEFINE_GUID(CLSID, CLSID_TESTv2,0xF560F763,0x2948,0x11D7,0xA9,0xBF,0x00,0x50,0xBA,0x24,0xC7,0xB9);
.
.
.

*************************************************************************************************

.c++ file

class CSink : public ITESTEvents
{
private:
DWORD m_dwRefCount;
public:

CSink::CSink() {m_dwRefCount = 0;}
CSink::~CSink() {}

void OnConfigurationApply(VARIANT_BOOL* pAccept);
void OnShowMessageDlg(IMsgDlg* pIMsg, VARIANT_BOOL* Result);
};


void main(){
.
.
.
CSink *pSink;
pSink = new CSink(); // ERROR MESSAGE
.
.
}

*************************************************************************************************
I quickly checked the example. The CSink class in Figure 2 is incomplete and only shows a fraction of the class. It doesn't show the implementation of IUnknown, the basic COM interface. QueryInterface() is part of IUnknown. You need to complete the implementation of CSink.

If the above sounds "Unknown" to you, I recommend that you first read a good book of COM. It is not a simple topic to explain here.
Once you have your example working, I suggest you don't use them in a real world project. They're more trouble than they're worth.
@webJose
This sounds not really unknown to me. I've read a few things about that in the last days. But in the "best" example I've found on the following webpage http://msdn.microsoft.com/en-us/magazine/cc163361.aspx the

IUnknown *pSinkUnk;
hr = pSink->QueryInterface (IID_IDispatch,(void **)&pSinkUnk);

will be done after the
CSink *pSink;
pSink = new CSink(); // ERROR MESSAGE
in the void main. In this example there is nothing in the CSink class. Do you know wehere I can find an example(maybe an webpage) where I can read something about this?
Any hints for an good book about COM are welcome :-).

@kbw
Why souldn't I use this in an real world project? What kind of problems do you mean? Is there another better way to do this?
By far, the best real book of COM I have ever read is Essential COM by Don Box.

http://www.amazon.com/Essential-COM-Don-Box/dp/0201634465

It will explain COM and why COM is the way it is. It will also give you pointers and several excellent code snippets that you can reuse. You must, however, be proficient in C++ as the author will not explain a single piece of syntax to you.

Besides a good book, you can read MSDN online. Back in year 2000 I read around 70% of the COM topics there. That is how I started.


hr = pSink->QueryInterface (IID_IDispatch,(void **)&pSinkUnk);


Note that the line above just uses QueryInterface(). It is not declaring it, and it is certainly not implementing it. Your compiler error states that no implementation for QueryInterface() exists. It is not complaining because QueryInterface() is being called from a null pointer.
Whereas COM and COM based technologies are theoretically sound, they're a real pain to deal with in a strictly typed language such as C++ as you spend a lot your time dealing with types determined later on and bending the language to deal with that in a typesafe way. "Connection Points" is COM way of doing callbacks.

If you want to use COM technologies, use C# and .NET. There's no value in trying to do all this in C or C++.
Unless you need your component to work under WinPE where .Net means nothing.
In which case, why are you using COM?
kbw, is that directed to me? Sorry, it is unclear to me.
Topic archived. No new replies allowed.