如何在Golang中使用zlib包装?

3
我尝试通过使用cgo从golang调用c zlib来修复最慢的zip实现,但是我遇到了一个错误。错误信息为:'deflateInit'未声明(在此函数中首次使用)。deflateInit在zlib.h中定义。是否有遗漏?感谢任何提示。
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
}

2
请添加: a) 您在上述源代码中使用了哪个完整的命令? b) 相对于“zlib.h”所在的位置,上述源代码位于何处? - zzzz
a) 我只是使用 go run cgotest.go b) 上述源代码位于 /Volumes/MacintoshHD/Users/dawn/Documents/workspace/work/dev/sandbox/testgo/src/cgotest c) zlib.h 可以在许多地方找到,我将 include 更改为 #include "/opt/local/include/zlib.h" 但问题仍然存在 你能在你的电脑上编译这个吗? - davyzhang
尝试了一段时间,但没有成功。谷歌搜索也没有帮助 :-( - zzzz
1个回答

7
这是您代码的修正版。请注意,要链接zlib库需要添加#cgo LDFLAGS: -lz;另外增加了一个小的C函数myDeflateInit,用于处理deflateInit是宏而不是函数的情况。同时,请注意strm定义的变化。
很遗憾,在Go中处理C宏可能会有些烦人,我想不到更好的方法,只能使用一个小型的C桥接函数。
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)
}

哦,原来 Golang/Cgo 对宏处理不正确,我明白了!非常感谢您提供的修复版本,对我帮助很大! - davyzhang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接