Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Win32 COM Programming in Pure C

Tags:

c

com

winapi

I have a programming project which requires access to some of the lower-level Windows APIs (WASAPI, in particular). I am fairly experienced with higher-level programming languages such as C#, Java, and PHP, and I know only a little bit about C/C++.

I would like to use C (not C++) for this project, as C++ is kind of scary. Upon changing the C/C++ settings of my project in Visual Studio to compile as C code, I noticed that any calls to __uuidof won't work, as they are C++ specific.

My question is twofold:

  1. Is it possible to write Win32 programs that utilize COM in pure C, and
  2. If so, should using pure C be avoided?
like image 369
Sam Avatar asked Feb 07 '13 06:02

Sam


People also ask

What is COM in C?

In conclusion, a COM object is basically a C++ class. A C++ class is just a struct that always starts with a pointer to its VTable (an array of function pointers). And the first three pointers in the VTable will always be named QueryInterface , AddRef , and Release .

What is WinAPI in C?

The Windows API, informally WinAPI, is Microsoft's core set of application programming interfaces (APIs) available in the Microsoft Windows operating systems.

What is the use of Windows h in C?

h is a Windows-specific header file for the C and C++ programming languages which contains declarations for all of the functions in the Windows API, all the common macros used by Windows programmers, and all the data types used by the various functions and subsystems.

What is the use of Win32 API?

Alternatively referred to as the Windows API and WinAPI, Win32 is the main set of Microsoft Windows APIs used for developing 32-bit applications. These APIs are responsible for functions in the following categories: Administration and Management - Install, configure, and service applications or systems.


2 Answers

  1. Yes it is possible to use write pure C programs that utilize COM, in fact that was common practice 10-15 years ago.

  2. You are not doing yourself a favor by using C (as you already have noticed). E.g. ATL provides lots of help when you are doing COM and can help you to avoid common mistakes.

If I were you I would go the C++ even if the threshold may be a bit higher at first. Also get a book in the subject if you do not have one. There are lots of examples to be found in the net but it is good to have something that leads you by the hand since COM programming is not for the faint of heart, regardless whether you use C or C++.

like image 50
AndersK Avatar answered Oct 13 '22 22:10

AndersK


COM uses a pretty small subset of C++ beyond the C part, and there's no requirement to use many of the 'scary' items such as:

  • Exceptions - these can really bite you in C++ if you don't get them right (you need to really buy into the RAII idiom, which can take getting used to if you're used to more traditional C/Win32 coding); but exceptions are not part of COM at all: COM uses return codes for all error handling. There are some wrappers and compiler extensions that will convert COM's return codes into C++ exceptions if you want, but it's opt-in.

  • Class hierarchies and inheritance - Inheritance is also not really part of COM itself, other than the fact that all COM interfaces derive from (or, start off with the methods from) IUnknown. But you don't need to know anything about multiple virtual inheritance to use COM. Some of this is very useful to know if you are implementing COM objects yourself, but not to just use it. (For example, using C++ multiple inheritance is a very common way to implement a COM object that exposes multiple interfaces; but it's not the only way.)

  • Templates - again, not part of COM, but there are several libraries - eg. MFC and ATL - that use templates to make COM a lot simpler to use. This is especially true for smart pointer classes like CComPtr that will take care of some reference counting for you, allowing your code to concentrate on doing the real interesting stuff instead of having it packed with housekeeping stuff.

The main link between COM and C++ is all C++ compilers on Windows will lay out a C++ object in memory in a way that matches exactly what COM requires. This allows you to use a COM object as though it were a C++ object, which makes the code considerably less verbose, as the language/compiler is taking care of some really simple but verbose stuff for you.

So instead of doing the following in C (step through vtable and pass this param explicitly):

pUnk->lpVtbl->SomeMethod(pUnk, 42);

You can do the following in C++:

pUnk->SomeMethod(42);

You really don't want to have to type ->lpVtbl and make sure you pass the correct 'this' parameter (be careful when cutting and pasting!) with every single COM call you make, do you?

My suggestion would be to find a good COM book - Inside COM is a good one - and just start off using the C++ subset that you are comfortable with. Once you know how to use a COM pointer "raw", and use QI, AddRef and so on yourself, then perhaps you can play with the helper libraries that use templates to do some of the bookkeeping for you. Deciding to use wrappers that map COM errors to C++ exceptions is a bit of a bigger jump, as you need to write C++ code that is exception-safe first so need to understand the various issues with those first. But I can't think of any good reason - other than sheer curiosity - for going back and using COM from plain C.

like image 36
BrendanMcK Avatar answered Oct 13 '22 22:10

BrendanMcK