Cgo的准备工作

  1. 安装msys2

  2. 在MSYS2 MINGW64中将Go的bin加入到path(比如.bashrc

    export PATH="/c/Program Files/Go/bin:$PATH"
    

    确认go在msys2中是可用的即可

  3. 安装工具链

    pacman -S --needed base-devel mingw-w64-x86_64-toolchain
    

    选择GCC

  4. 可以通过以下代码确认Cgo

    package main
    
    /*
    #include <stdio.h>
    
    void Hello(){
        printf("Hello world\\n");
    }
    */
    import "C"
    
    func main() {
    	C.Hello()
    }
    

Windows编译libdmtx

  1. clone仓库

    git clone <https://github.com/dmtx/libdmtx.git>
    
  2. 安装autoconf

    pacman -S autoconf automake libtool
    
  3. 开始编译

    ./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图片。