Thanks everyone. I eventually made it work quite simply by using a combination of the suggestions here. The app's Linux build uses the traditional main() entry point which does very little, apart from calling a function called app_main(). The Windows build uses the traditional WinMain() which builds some argc and argv info and then passes it to the same app_main() function. I just needed to add these blue lines to make it all work:-

Code:
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
int   ret  = (-1);

	// Some stuff here to create argc and argv info

	BOOL bConsole; FILE *pStdOut = NULL, *pStdErr = NULL;
	if ((bConsole = AttachConsole(ATTACH_PARENT_PROCESS)) != 0)
	{
		// This only gets reached if we started from a console
		pStdOut = freopen( "CONOUT$", "w", stdout );
		pStdErr = freopen( "CONOUT$", "w", stderr );
	}
		
	ret = app_main (argc, argv);

	if (pStdOut)
		fclose (pStdOut);
	if (pStdErr)
		fclose (pStdErr);
	if (bConsole)
		FreeConsole();

	return ret;
}
Seems to be working a treat so far. When started from a console, the app sends its output to the console window and it also closes down if I close the console, which is quite neat. The only (very minor) niggle is that the app doesn't detach itself cleanly from the console if I close the GUI app but leave the console open. After the app closes I need to select the console window and type a carriage return before I see the DOS prompt again. That's only a minor problem though. Apart from that it works great.