C++ demo code for interaction with C I want to show how to interact with C from C++ and chose a simple and small library to demonstrate. zlib's gzopen, gzwrite and gzclose looked like a reasonably closed set of funtions.

Does anyone see anything fundamentally wrong with my presentaion? The main code I present here is in class GzWrite.

Intro section:

#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;fstream&gt; // ifstream
#include &lt;stdexcept&gt; // runtime_error
#include &lt;iostream&gt; // cerr
// C-Headers:
#include &lt;zlib.h&gt; // gzXyz; sudo aptitude install libz-dev
#include &lt;string.h&gt; // strerror
#include &lt;errno.h&gt; // errno
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
using std::ifstream; using std::ofstream; using std::string; using std::vector;
namespace {

constexpr size_t BLOCK_SZ = 256*1024;
constexpr int LEVEL = Z_DEFAULT_COMPRESSION;


Core class

struct GzWrite { // RAII-Wrapper
    gzFile gz_ ; // C-Struct aus zlib.h
    explicit GzWrite(const string&amp; filename)
        : gz_{gzopen(filename.c_str(),"wb9")} // 'w': write, 'b':binary, '9':level
    {
        if(gz_==NULL) throw std::runtime_error(strerror(errno));
    }
    ~GzWrite() {
        gzclose(gz_);
    }
    int write(const char* data, size_t len) {
        return gzwrite(gz_, data, len);
    }
    GzWrite(const GzWrite&amp;) = delete; // no copy
    GzWrite&amp; operator=(const GzWrite&amp;) = delete; // no assign
};


Helper functions 

vector&lt;char&gt; read(const string&amp; infn) {
    ifstream inf{ infn, ifstream::binary };
    if(!inf) throw std::runtime_error("open error");
    inf.seekg(0, inf.end); // go to end of file
    const auto laenge = inf.tellg(); // current pos is file size
    if(laenge &gt; 1024*1024*1024) throw std::runtime_error("&lt;1GB please");
    inf.seekg(0, inf.beg); // back to begin
    vector&lt;char&gt; data(laenge); // make room
    inf.read(data.data(), laenge); // read all at once
    return std::move(data); // make doubly sure data is not copied
}

void pack(const string&amp; infn, const string&amp; outfn) {
    vector&lt;char&gt; indata = read(infn); // read input
    GzWrite gz{outfn}; // init output
    auto res = gz.write(indata.data(), indata.size());
    if(res==0) throw std::runtime_error("write error");
}

} // namespace


Main function:

int main(int argc, const char* argv[]) {
    try {
        const vector&lt;string&gt; fnamen {argv+1, argv+argc};
        for(auto fname : fnamen) {
            std::cout &lt;&lt; "packing " &lt;&lt; fname &lt;&lt; "... ";
            pack(fname, fname+".gz");
            std::cout &lt;&lt; fname &lt;&lt; ".gz"&lt;&lt; "\n";
        }
    } catch(std::runtime_error exc) {
        std::cerr &lt;&lt; "Error: " &lt;&lt; exc.what() &lt;&lt; "\n";
    }
}
This example is mostly about making and using a RAII wrapper, not about calling C from C++ (which is trivial).

If you want to show how to call C-like interfaces, then use zlib directly, without wrapping it.

If you want to show the native C++ way to wrap a C interface, then the wrapper should be an iostream subclass, like gzstream.

pack should read blocks of finite size rather than reading the whole file at once. It's a compression utility, so it's likely to be used on files that won't fit in memory!

Some confusing names:


GzWrite instances aren't writes; they're streams. How about GzStream or (if it uses the iostreams interface) gzostream?
Don't call a function read; it's easy to confuse with Posix read. This is traditionally called slurp or read_file.
infn will probably be interpreted as "in-function", not "in-filename". How about infile?
laenge (Länge?): length


BLOCK_SZ and LEVEL are unused.