Cgo的准备工作
-
安装msys2
-
在MSYS2 MINGW64中将Go的bin加入到path(比如.bashrc
export PATH="/c/Program Files/Go/bin:$PATH"
确认go在msys2中是可用的即可
-
安装工具链
pacman -S --needed base-devel mingw-w64-x86_64-toolchain
选择GCC
-
可以通过以下代码确认Cgo
package main /* #include <stdio.h> void Hello(){ printf("Hello world\\n"); } */ import "C" func main() { C.Hello() }
Windows编译libdmtx
-
clone仓库
git clone <https://github.com/dmtx/libdmtx.git>
-
安装autoconf
pacman -S autoconf automake libtool
-
开始编译
./autoconf ./configure make make install #这一步就会产生一个.libs文件夹,里面就是Cgo需要的文件
Cgo调用libdmtx
package main
/*
#cgo windows LDFLAGS: -L. -ldmtx
#cgo windows CFLAGS: -I.
#cgo darwin || linux LDFLAGS: -ldmtx
#include <stdlib.h>
#include <dmtx.h>
#include <stdio.h>
#include <string.h>
*/
import "C"
import (
"image"
"image/color"
"image/png"
"os"
"unsafe"
)
func main() {
encode, err := Encode("hello,world")
if err != nil {
panic(err)
}
outputFile, err := os.Create("test.png")
defer outputFile.Close()
if err != nil {
panic(err)
}
_ = png.Encode(outputFile, encode)
}
func Encode(code string) (image.Image, error) {
str := (*C.uchar)(C.CBytes([]byte(code)))
enc := C.dmtxEncodeCreate()
C.dmtxEncodeDataMatrix(enc, C.int(len(code)), str)
width := C.dmtxImageGetProp(enc.image, C.DmtxPropWidth)
height := C.dmtxImageGetProp(enc.image, C.DmtxPropHeight)
bytesPerPixel := C.dmtxImageGetProp(enc.image, C.DmtxPropBytesPerPixel)
bytedata := C.GoBytes(unsafe.Pointer(enc.image.pxl), C.int(width*height*bytesPerPixel))
C.dmtxEncodeDestroy(&enc)
w := int(width)
h := int(height)
result := image.NewRGBA(image.Rect(0, 0, int(width), int(height)))
for y := 0; y < h; y++ {
for x := 0; x < w; x++ {
a := bytedata[(x+y*w)*3]
if a > 0 {
result.SetRGBA(x, y, color.RGBA{A: 255, R: 255, G: 255, B: 255})
} else {
result.SetRGBA(x, y, color.RGBA{A: 255, R: 0, G: 0, B: 0})
}
}
}
return result, nil
}
build出来的exe可以直接生成一张code图片。