package libgofunc import ( /* #include */ "C" _ "image/png" "os" "strings" "bufio" "log" "net" "time" "github.com/kenshaw/escpos" ) import ( "fmt" "github.com/google/gousb" ) type USBReadWriter struct { out *gousb.OutEndpoint in *gousb.InEndpoint // Optional, can be nil if you only write } func (urw *USBReadWriter) Write(p []byte) (n int, err error) { return urw.out.Write(p) } func (urw *USBReadWriter) Read(p []byte) (n int, err error) { if urw.in == nil { return 0, fmt.Errorf("read not supported") } return urw.in.Read(p) } //export PrintImg func PrintImg(printer *C.char, imagePath *C.char) *C.char { goPrinter := C.GoString(printer) goImagePath := C.GoString(imagePath) var out *gousb.OutEndpoint // printer := "tcp:192.168.100.151:9100" // printer := "usb:/dev/usb/lp1" var w *bufio.ReadWriter if strings.HasPrefix(goPrinter, "tcp:") { location := strings.TrimLeft(goPrinter, "tcp:") conn, err := net.Dial("tcp", location) if err != nil { log.Println("error dialing:", err.Error()) return NewErr(err) } defer conn.Close() w = bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn)) } else if strings.HasPrefix(goPrinter, "usb:") { location := strings.TrimLeft(goPrinter, "usb:") f, err := os.OpenFile(location, os.O_RDWR, os.ModeDevice) if err != nil { log.Println("error OpenFile usb:", err.Error()) return NewErr(err) } defer f.Close() w = bufio.NewReadWriter(bufio.NewReader(f), bufio.NewWriter(f)) } else if strings.HasPrefix(goPrinter, "int:") { ctx := gousb.NewContext() // location := strings.TrimLeft(goPrinter, "int:") targetBus := 1 targetAddr := 5 devs, err := ctx.OpenDevices(func(desc *gousb.DeviceDesc) bool { return int(desc.Bus) == targetBus && int(desc.Address) == targetAddr }) if err != nil || len(devs) == 0 { log.Fatal("Could not find or open the device") } dev := devs[0] defer dev.Close() dev.SetAutoDetach(true) // 2. Claim the default interface (usually 0 for printers) // Note: This may require detaching the kernel driver on Linux intf, done, err := dev.DefaultInterface() if err != nil { log.Fatalf("Failed to claim interface: %v", err) } defer done() // 3. Open the Bulk Output Endpoint (usually endpoint #1 or #2) // You may need to inspect desc.Endpoints to find the correct Bulk Out ID out, err = intf.OutEndpoint(1) if err != nil { log.Fatalf("Failed to open OUT endpoint: %v", err) } // w = bufio.NewReadWriter(bufio.NewReader(outPort), bufio.NewWriter(f)) rw := &USBReadWriter{out: out} reader := bufio.NewReader(rw) writer := bufio.NewWriter(rw) w = bufio.NewReadWriter(reader, writer) } prt := escpos.New(w) prt.Init() prt.SetSmooth(1) err := printImg(prt, goImagePath) if err != nil { return NewErr(err) } prt.Cut() prt.End() w.Flush() time.Sleep(100 * time.Millisecond) return NewOk(nil) } func Print(printer, imagePath string) string { result := PrintImg(C.CString(printer), C.CString(imagePath)) r := C.GoString(result) return r }