Porting C/C++ to/from Win32 & Unix - A C/C++ Rosetta Stone
The following few tables and notes are a few that were compiled during the process of porting Qu-Prolog from Unix to Win32. They are by no means complete, and probably inaccurate in a few details, but I have found them to be a great help when porting software in either direction.
Please note that threading is not discussed, as the ported application that these notes are based on contains its own scheduler and threading implementation.
Update: If you're interested in porting applications with threading, check out the pThreads-Win32 Project.
#include Porting Lookup Table:
|Any network includes||
Code and Function Porting Lookup Table:
Benchmarks using native Win32 Code:
It was previously mentioned that Cygwin caused a 40% decrease in performance using benchmarks under both Windows and Unix. The native port, however, showed no noticeable performance decrease whatsoever in the benchmarks used.
Making TCP Work:
Unlike under Unix, before a socket created on Windows using the WinSock library is used, it must be initialized using the following call:
WSADATA wsaData; WORD wVersionRequested = MAKEWORD( 2, 2 ); int err = WSAStartup( wVersionRequested, &wsaData );
Once this code is executed, then socket operations may be used. Without it, you get an error code of 10093 (“Either the application has not called WSAStartup, or WSAStartup failed.”)
Another potential problem is with conflicts between the platform SDK and WinSock2. Originally, we had not planned to use WinSock2, as there was no need for any of the additional API calls; however, as the Elvin Libraries depended on WinSock2, we decided that we should use to avoid difficulties. This, however, caused problems itself. Duplicate definitions occured for many structs and method prototypes. A solution for this was to make sure that these headers were always included in the following order, with the
#define always added.
#include <winsock2.h> #define WINSOCKAPI #include <windows.h>
Polling for Input on a File Descriptor - Making sure a read() won't block:
select() works on all types of file descriptors. Under Win32, however, select() only works on file descriptors from Winsock - ie:
select() can only poll sockets. This caused/is causing major problems with polling stdin and file descriptors on files which are handled in Qu-Prolog with low C-level calls (eg:
open() and friends).
Instead of file descriptors, windows uses handles instead for this type of code. In order to obtain a handle from a file descriptor, the following code is used:
handle = (HANDLE)_get_osfhandle(fd)
Depending on whether we're polling a set of file descriptors or a single file descriptor, there are two separate functions that we can use:
result = WaitForMultipleObjects(hcount + 1, handles, true, NULL)
result = WaitForSingleObject(fd,0)