Friday 1 October 2010

Safely including "winsock2.h" and "windows.h" at the same time.

Today, I learned that including "windows.h" and "winsock2.h" at the same time can cause compile-time errors. As soon as I included "winsock2.h" the compiler started complaining about some symbols being redefined.

It turns out that
  • "windows.h" includes "winsock.h" and
  • "winsock.h" and "winsock2.h" contain definitions of some of the same symbols.
So if you include both "windows.h" and "winsock2.h" some symbols may be redefined. I say "may be redefined" because there are ways to prevent this.

Solution #1
The first solution I considered was to make sure "winsock2.h" is included before "windows.h".

This works because "winsock2.h" defines _WINSOCKAPI_ which prevents the compiler from seeing the contents of "winsock.h" ("winsock.h" is guarded by the following):

#ifndef _WINSOCKAPI_
#define _WINSOCKAPI_

...
Contents of winsock.h
...

#endif  /* _WINSOCKAPI_ */

So if _WINSOCKAPI_ is already defined, the entire file is skipped.

I didn't really like this solution because I don't like relying on header files being included in any particular order (and it's just too much hassle).

Solution #2
The second solution, which I discovered while searching on the Internet, is to define WIN32_LEAN_AND_MEAN before including "windows.h".

This works because defining WIN32_LEAN_AND_MEAN prevents "windows.h" from including several header files (including "winsock.h").

I almost used this solution, but I was concerned that it was doing more than I really need. It was preventing "windows.h" from including a number of header files, not just the one I wanted.

Solution #3
The solution I decided to use was to define _WINSOCKAPI_ before including "windows.h".

This works for the same reason Solutions #1 works, it prevents the compiler from seeing the contents of "winsock.h".

Not Perfect
Solution #3 is not quite perfect because I still have to make sure to define _WINSOCKAPI_ before including "windows.h".

The perfect solution I think would be for Microsoft to modify "windows.h" so that the inclusion of "winsock.h" is conditional on a symbol being undefined. For example:

#ifndef WIN32_NO_WINSOCK_H
#include #include <winsock.h>
#endif

Tuesday 20 October 2009

Introducing StrongLib

Introduction
This is the first post for "Web Programming in C", so now is a perfect time to answer some questions about this blog, for example: What is StrongLib? Why is it being created? Why should you care?

What is StrongLib?
OK, easy question first. StrongLib is the name I've come up with for what will hopfully be a series of C libraries that will make it easy to write web programs in C. What kinds of web programs? Well, to start, two kinds:
  • Web Server applications. The kinds of applications, that PHP and ASP are currently used for.
  • Desktop applications that consume services from the web.
Why Create StrongLib?
I have been building the next release of Irie Pascal, which is going to be focussed on web programming, and I decided that it makes sense to create a seperate library to handle all of the web programming details, and then create the next release of Irie Pascal on top of that library.

StrongLib Foundation
The first StrongLib library is the foundation library, StrongLib Foundation. So far the design goals for this library are:
  • Provide a low-to-mid level API for common web operations (e.g. with functions for processing Unicode, and using sockets.
  • Make it easier to write portable code for all of the operating systems supported by Irie Pascal, namely Windows, Linux, FreeBSD, and Solaris. I am not tring to create some some big complicated cross-platform library that takes over your application. I just want to eliminate some of the really unnecessary differences between OS APIs (the different but functionally equivalent APIs for thread creation for example).
Learning how to use Blogger
This is my first blog on Blogger (I was using Wordpress before), so this first post is also kind of an experiment.