Search code examples
gozlibcgo

how can I wrap zlib in golang?


I tried to fix the golang's slowest zip implementation by calling the c zlib from golang using cgo

but I get an error

error: 'deflateInit' undeclared (first use in this function)

deflateInit is defined in zlib.h

Am I missing something? thanks for any hints.

package main

/*
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "zlib.h"
*/
import "C"

import (
    "fmt"
)

func main() {
    fmt.Println("hmmm....")
    fmt.Println(int(C.random()))
    var strm C.struct_z_stream
    fmt.Println(strm)
    ret := C.deflateInit(&strm, 5) // trouble here
}

Solution

  • Here is a fixed version of your code. Note the #cgo LDFLAGS: -lz to link with the zlib library and the little C function myDeflateInit which deals with the fact that deflateInit is a macro rather than a function. Note also the change in definition of strm.

    C macros are rather irritating to deal with from Go unfortunately - I couldn't think of a better way than a small C shim function.

    package main
    
    /*
    #cgo LDFLAGS: -lz
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <assert.h>
    #include "zlib.h"
    
    int myDeflateInit(z_streamp s, int n) {
         return deflateInit(s, n);
    }
    */
    import "C"
    
    import (
        "fmt"
    )
    
    func main() {
        fmt.Println("hmmm....")
        fmt.Println(int(C.random()))
        var strm C.z_stream
        fmt.Println(strm)
        ret := C.myDeflateInit(&strm, 5)
        fmt.Println(ret)
    }