Called the library created by Go from mruby on Windows and displayed the image of the web camera at the command prompt
Tags: mruby, windows, go
Published: 2017-11-16 01:32:41

---
title: Called the library created by Go from mruby on Windows and displayed the image of the web camera at the command prompt
published: true
description: 
tags: mruby,windows,go
---

# background

I created a library in Go language specifying files and URLs at the Windows command prompt and displaying images at the command prompt

# Preparation

The Go side inputs jpeg and png as the input source, as it is, it will call from mruby via the file as it is, worrying about the burden on the SSD w. Of course speed too.

## To treat the start address passed from C as a slice of Go

I found this link:

- https://github.com/golang/go/issues/13656

Apparently,

- https://github.com/golang/go/wiki/cgo#Turning_C_arrays_into_Go_slices

It seems to be nice to write (there seems to be a limitation on the capacity up to 2 GB ..)

```go
func termPutImage(imageData *C.uchar, width, height C.int) {
    len := 3 * width * height
    slice := (*[1 << 30]C.uchar)(unsafe.Pointer(imageData))[:len:len]
```

## To convert to the Image type of Go language

As shown below, we were able to convert the array (P6 format of PPM) received from C side to Image type.

```go
img := image.NewRGBA(image.Rect(0, 0, int(width), int(height)))
for h := 0; h < int(height); h++ {
    for w := 0; w < int(width); w++ {
        r := uint8(slice[3*(h*int(width)+w)])
        g := uint8(slice[3*(h*int(width)+w)+1])
        b := uint8(slice[3*(h*int(width)+w)+2])
        c := color.RGBA{r, g, b, 0}
        img.SetRGBA(w, h, c)
    }
}
```

## To make libhogehoge.a format as Go

On Windows, shared libraries can not be created, but output of archive format libraries is supported.

```shell
go build -buildmode = c-archive -o libimgtype.a main.go
```

This creates a library in .a format. For MinGW's gcc environment, you can use it immediately.

## Make MSVC mruby available create a lib file and link

The mrbgem named [mruby-webcam](https://github.com/kjunichi/mruby-webcam) we are about to use this time uses the MSVC version of OpenCV, and according to it, we will use MSVC.

Therefore, prepare a def file and generate a. Dll format from this and the .a(archive) format library of the previous. Also, generate the necessary .lib file from .def when linking in MSVC processing system. It will be necessary to do some troublesome work.

# How to make a dll

The DLL went with the MinGW version of gcc (gcc specified with cgo).

```shell
gcc -m64 -shared -o imgtype.dll imgtype.def libimgtype.a -Wl,--allow-multiple-definition -static -lwinmm -lntdll -lWs2_32 
```

# How to create a lib file

The. lib file is done with the lib command attached to MSVC.

```shell
lib /machine:x64 /def:imgtype.def
```

Now I am ready to integrate into MSVC mruby.

- https://github.com/kjunichi/libimgtype

# Calling Go from mruby

If you come here, you only write mrbgem. Write the created. Lib file in mrbgem.rake as follows:

```ruby
spec.linker.flags_before_libraries << "imgtype.lib"
```

You can pass the path to the imgtype.lib file to the environment variable LIB, and mruby.exe and mirb.exe can be created by incorporating Go library with rake.

# To run

This mrb gem is required below:

```ruby
conf.gembox 'default'
conf.gem '../mruby-webcam'
conf.gem '../mruby-imgtype'
conf.gem :github => 'matsumoto-r/mruby-sleep'  
```

Below is a mruby script that displays the webcam image at the command prompt or Vim: terminal.

```ruby
Imgtype.init

cam = Webcam.new
cam.setFmt "ppm"
cam.capture {|img|
  Imgtype.imgtype img
}
while true
    cam.snap
    Sleep::usleep(1000)
    if Imgtype.get_key == "ESC" then
        break
    end
end
Imgtype.close
```

# Result

Imgtype.get_key reads Windows API directly and responds. I was surprised to get key input without polling.

- https://t.co/gtYXg0tOA3