That presumably applies to C too. In that case why all the fuss in
this
thread? Or maybe:
(from an expert in writing C compilers specific to Windows) using
COM isn't
as simple as you seem to be implying.
He was talking about reimplementing his compiler so that it ran as a
metro app (which is pretty crazy to even think about, and as he's
been told, he doesn't need to do that; the desktop still exists in
Windows 8). He wasn't talking about using COM in general.
But, seeing as you're the expert, perhaps you can give an example
in writing
a simple task in C to run under Windows, without using 'stone-age'
DLLs and
without a console. Such as Hello, World (just an alert box will
do). You
might need to explain exactly how the executable that the C is
compiled to,
actually talks to Windows.
When I said "stone age" I was referring to DLL-exported functions,
not about DLLs themselves. COM components are DLLs anyway (or EXEs
sometimes).
Anyway, the easiest way to create a COM component in C++ is with ATL.
There isn't an equivalent for C, but you can do it without ATL (be it
C or C++), although you have to do manually a lot of the things VS
does for you.
First thing is to create an interface in an IDL (Interface Definition
Language) file for the functionality you need:
[uuid(CBC6B4ED-107C-43b3-BA0A-054E6430F435), object]
interface IHelloCom : IUnknown
{
HRESULT SayHello();
}
Then you compile the IDL file with the MIDL compiler, which creates
the equivalent interfaces in C or C++. For C++ it gives:
MIDL_INTERFACE("CBC6B4ED-107C-43b3-BA0A-054E6430F435")
IHelloCom : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE SayHello( void) = 0;
};
For C it gives:
typedef struct IHelloComVtbl
{
BEGIN_INTERFACE
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
IHelloCom * This,
/* [in] */ REFIID riid,
/* [annotation][iid_is][out] */
__RPC__deref_out void **ppvObject);
ULONG ( STDMETHODCALLTYPE *AddRef )(
IHelloCom * This);
ULONG ( STDMETHODCALLTYPE *Release )(
IHelloCom * This);
HRESULT ( STDMETHODCALLTYPE *SayHello )(
IHelloCom * This);
END_INTERFACE
} IHelloComVtbl;
interface IHelloCom
{
CONST_VTBL struct IHelloComVtbl *lpVtbl;
};
Then you need to implement the interface:
class __declspec(uuid("7A5F33E4-F4B8-4932-9207-1EF2B642C910"))
HelloCom : public IHelloCom {
public:
// IUnknown methods:
HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject)
{ ... } ULONG __stdcall AddRef() { ... }
ULONG __stdcall Release() { ... }
// IHelloCom methods:
HRESULT __stdcall SayHello()
{
MessageBox(nullptr, L"Hello COM!", L"Hello COM", 0);
return S_OK;
}
};
I don't really know how to do that one in C.