What worked for me was Ulrich suggestion to use boost iostreams library:
My system config is Windows 7, GCC 5.1.0, Boost 1_64_0.
My single test.cpp file is:
#define STRICT 1
#include <windows.h>
#include <cstddef>
#include <cstdio>
#include <cstdint>
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
namespace io = boost::iostreams;
int main()
{
HANDLE hFile = CreateFile(
"filename.txt",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL );
if ( hFile == INVALID_HANDLE_VALUE )
{
printf( "CreateFile failed %d\n", GetLastError() );
getchar();
return EXIT_FAILURE;
}
io::file_descriptor_sink fd_sink_device(
hFile,
io::never_close_handle );
io::stream_buffer<io::file_descriptor_sink> streambuf( fd_sink_device );
std::ostream os( &streambuf );
os << "File contents" << std::endl;
CloseHandle( hFile );
getchar();
return EXIT_SUCCESS;
}
the makefile I used was:
FLAGS = -std=c++14 -pedantic -Wextra -Wlogical-op
INCPATHBOOST = -I"$(BOOST)"
LIBPATHBOOST = -L"$(BOOST_LIB)"
LIBSBOOST = -l:libboost_iostreams-mgw51-mt-s-1_64.a
LIBSWIN = -l:libkernel32.a -l:libuser32.a -l:libshell32.a -l:libadvapi32.a\
-l:libws2_32.a -l:liboleaut32.a -l:libimm32.a -l:libwinmm.a -l:libole32.a\
-l:libuuid.a -l:libopengl32.a -l:libole32.a -l:libgdi32.a
all: test.exe
test.exe : test.o
g++ -static -mconsole $(LIBPATHBOOST) test.o $(LIBSBOOST) $(LIBSWIN) -o test.exe
test.o : test.cpp
g++ -c $(INCPATHBOOST) $(FLAGS) test.cpp
clean:
del test.o test.exe
Ok, you might argue not all of this is necessary to communicate. But when I speak for myself I've such an extreme dislike for any documentation that is incomplete that left me wondering how all of the concepts fit together to make an program work. This including the Boost iostreams documentation I've been fighting with today. So I hope my example will be useful for many people. And experts are very welcome to comment and improve.