Go言語で手動オブジェクト指向

仮想関数をインターフェースに書き出して、Self経由で呼び出す方式。

手順は、

  • 構造体とインターフェースを対にして作る
  • それぞれに埋め込みで継承していく
  • コンストラクタ関数で、Selfを伝搬させていく

こんなダサくて効率の悪いことは普通やらないが、GUIフレームワークのようにオブジェクト指向が合うものには、部分的に似たような構造が使われている感じがする。


package main

import (
	"fmt"
)

type IA interface {
	MethodA()
}

type A struct {
	Self IA
}

func (a *A) MethodA() {
	fmt.Println("A.MethodA")
}

func (a *A) CallMethodA() {
	fmt.Println("A.CallMethodA")
	a.Self.MethodA() // Self経由で呼び出す
}

func NewA(self IA) *A {
	a := &A{}
	if self != nil {
		a.Self = self
	} else {
		a.Self = a
	}
	return a
}

type IB interface {
	IA
	MethodB()
}

type B struct {
	*A
	Self  IB
	Super IA
}

func (b *B) MethodA() {
	fmt.Println("B.MethodA")
	b.Super.MethodA()
}

func (b *B) MethodB() {
	fmt.Println("B.MethodB")
}

func NewB(self IB) *B {
	b := &B{}
	if self != nil {
		b.Self = self
	} else {
		b.Self = b
	}
	b.A = NewA(b.Self)
	b.Super = b.A
	return b
}

type IC interface {
	IB
}

type C struct {
	*B
	Self  IC
	Super IB
}

func (c *C) MethodB() {
	fmt.Println("C.MethodB")
}

func NewC(self IC) *C {
	c := &C{}
	if self != nil {
		c.Self = self
	} else {
		c.Self = c
	}
	c.B = NewB(c.Self)
	c.Super = c.B
	return c
}

type ID interface {
	IC
}

type D struct {
	*C
	Self  ID
	Super IC
}

func (d *D) MethodA() {
	fmt.Println("D.MethodA")
	d.Super.MethodA()
}

func NewD(self ID) *D {
	d := &D{}
	if self != nil {
		d.Self = self
	} else {
		d.Self = d
	}
	d.C = NewC(d.Self)
	d.Super = d.C
	return d
}

func main() {
	d := NewD(nil)
	d.MethodA()
	// D.MethodA
	// B.MethodA
	// A.MethodA

	d.CallMethodA()
	// A.CallMethodA
	// D.MethodA
	// B.MethodA
	// A.MethodA

	d.MethodB()
	// C.MethodB
}

mingw版ruby(64bit)にcurbとrmagickのgemをインストール

RubyInstaller(x64) での場合

rmagickのインストール

ftp://ftp.imagemagick.org/pub/ImageMagick/binaries/
から、ImageMagick-6.9.5-Q16-x64-dll.exeをダウンロード、インストール
(ImageMagick-7.0.3-0はダメだったので)


※パスを通して、開発用のファイルもインストールすること

gemのインストール
gem install rmagick -- '--with-opt-dir="C:\dev\cmd\ImageMagick-6.9.5-Q16"'

curbのインストール

https://curl.haxx.se/gknw.net/7.40.0/dist-w64/curl-7.40.0-devel-mingw64.zip
↑のファイルをダウンロードして、適当な場所に配置。

gemのインストール
gem install curb -- '--with-curl-include="C:/dev/cmd/curl-7.40.0-devel-mingw64/include"' '--with-curl-lib="C:/dev/cmd/curl-7.40.0-devel-mingw64/bin"'

curl.exeの場所にパスを通すか、libcurl.dllをruby.exeの場所にコピー


動作テスト

require 'curb'
require 'rmagick'

easy = Curl::Easy.download("http://www.imagemagick.org/image/wizard.jpg")
p easy.downloaded_content_length #=> 68305.0

image = Magick::ImageList.new("wizard.jpg").first
p [image.columns, image.rows] #=> [265, 352]

KyotoCabinetのruby拡張をmingwでビルド(2)

RubyInstaller(x64)のRubyでkyotocabinetの拡張を使うためにビルドしようとしたが、なかなかうまくいかなかった。
結局、かなり滅茶苦茶なやり方でビルドしたので、自分以外の役には立たないかもしれない。

1.準備

MSYS2をインストール

msys2-x86_64-20160205.exeをダウンロードしてインストールした。

mingw64_shell.batを起動して、各種パッケージをインストール。

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

LZOは実用的な圧縮速度なので入れておく。

regexのビルド・インストール

mingw-libgnurx-2.5.1-src.tar.gzをダウンロードしてビルド。
参考サイト

nasu@HANA MINGW64 ~/mingw-libgnurx-2.5.1
$ ./configure --prefix=/mingw64
$ make
$ rm libregex.a
$ ar rcs libregex.a regex.o
$ make install

2. Kyoto Cabinet のビルド・インストール

kyotocabinet-1.2.76.tar.gzをダウンロード、展開。

configureを編集 (置換)

/usr/local/include → /mingw64/include
/usr/local/lib → /mingw64/lib

kcthread.ccの編集 (置換)

(::DWORD)opq_ → (::DWORD_PTR)opq_

ビルド
./configure --prefix=/mingw64 --enable-lzo
make
make install

3. KyotoCabinet の ruby拡張をビルド・インストール

kyotocabinet-ruby-1.32.tar.gzをダウンロード、展開。

各種ファイルの編集

・extconf.rbとtest.rbの Config を RbConfig に置換。
・kyotocabinet.ccの「#define _KC_YARV_」をコメントアウト
(※ちなみにrb_thread_blocking_regionの所をrb_thread_call_without_gvlで書き直してみたら、test.rbでbugに遭遇。)

ruby extconf.rb

Makefileを作成。
ここのrubyは、RubyInstallerでインストールしたruby
パスが通ってなかったら、/c/ruby23-x64/bin/ruby みたいに書けばいいはず。

MakefileのLIBSを編集して、ビルド

余計なdllを必要としないように試行錯誤。

LIBS = $(LIBRUBYARG_SHARED)  -lkyotocabinet -llzo2 -lz -lregex -lstdc++ -lpthread -lm -lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi  

↑この部分を、↓に書き換え。

LIBS = $(LIBRUBYARG_SHARED)  -lkyotocabinet -lz -static-libgcc -Wl,-Bstatic -llzo2 -lregex -lstdc++ -lpthread -lm -Wl,-Bdynamic -lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi  

ビルド、テスト

make
make install
ruby test.rb

テストはwickedの所が全部failed。大丈夫なのかな?

まとめ

まあデータを突っ込むのに使えればいいかなという感じです

# 文字コードを設定
db.tune_encoding(Encoding::UTF_8)

window message

適当に抜き出しただけ

0 WM_NULL
1 WM_CREATE
2 WM_DESTROY
3 WM_MOVE
5 WM_SIZE
6 WM_ACTIVATE
7 WM_SETFOCUS
8 WM_KILLFOCUS
10 WM_ENABLE
11 WM_SETREDRAW
12 WM_SETTEXT
13 WM_GETTEXT
14 WM_GETTEXTLENGTH
15 WM_PAINT
16 WM_CLOSE
17 WM_QUERYENDSESSION
18 WM_QUIT
19 WM_QUERYOPEN
20 WM_ERASEBKGND
21 WM_SYSCOLORCHANGE
22 WM_ENDSESSION
24 WM_SHOWWINDOW
26 WM_WININICHANGE
26 WM_SETTINGCHANGE
27 WM_DEVMODECHANGE
28 WM_ACTIVATEAPP
29 WM_FONTCHANGE
30 WM_TIMECHANGE
31 WM_CANCELMODE
32 WM_SETCURSOR
33 WM_MOUSEACTIVATE
34 WM_CHILDACTIVATE
35 WM_QUEUESYNC
36 WM_GETMINMAXINFO
38 WM_PAINTICON
39 WM_ICONERASEBKGND
40 WM_NEXTDLGCTL
42 WM_SPOOLERSTATUS
43 WM_DRAWITEM
44 WM_MEASUREITEM
45 WM_DELETEITEM
46 WM_VKEYTOITEM
47 WM_CHARTOITEM
48 WM_SETFONT
49 WM_GETFONT
50 WM_SETHOTKEY
51 WM_GETHOTKEY
55 WM_QUERYDRAGICON
57 WM_COMPAREITEM
61 WM_GETOBJECT
65 WM_COMPACTING
68 WM_COMMNOTIFY
70 WM_WINDOWPOSCHANGING
71 WM_WINDOWPOSCHANGED
72 WM_POWER
74 WM_COPYDATA
75 WM_CANCELJOURNAL
78 WM_NOTIFY
80 WM_INPUTLANGCHANGEREQUEST
81 WM_INPUTLANGCHANGE
82 WM_TCARD
83 WM_HELP
84 WM_USERCHANGED
85 WM_NOTIFYFORMAT
123 WM_CONTEXTMENU
124 WM_STYLECHANGING
125 WM_STYLECHANGED
126 WM_DISPLAYCHANGE
127 WM_GETICON
128 WM_SETICON
129 WM_NCCREATE
130 WM_NCDESTROY
131 WM_NCCALCSIZE
132 WM_NCHITTEST
133 WM_NCPAINT
134 WM_NCACTIVATE
135 WM_GETDLGCODE
136 WM_SYNCPAINT
160 WM_NCMOUSEMOVE
161 WM_NCLBUTTONDOWN
162 WM_NCLBUTTONUP
163 WM_NCLBUTTONDBLCLK
164 WM_NCRBUTTONDOWN
165 WM_NCRBUTTONUP
166 WM_NCRBUTTONDBLCLK
167 WM_NCMBUTTONDOWN
168 WM_NCMBUTTONUP
169 WM_NCMBUTTONDBLCLK
171 WM_NCXBUTTONDOWN
172 WM_NCXBUTTONUP
173 WM_NCXBUTTONDBLCLK
254 WM_INPUT_DEVICE_CHANGE
255 WM_INPUT
256 WM_KEYDOWN
256 WM_KEYFIRST
257 WM_KEYUP
258 WM_CHAR
259 WM_DEADCHAR
260 WM_SYSKEYDOWN
261 WM_SYSKEYUP
262 WM_SYSCHAR
263 WM_SYSDEADCHAR
265 WM_KEYLAST
265 WM_WNT_CONVERTREQUESTEX
265 WM_UNICHAR
266 WM_CONVERTREQUEST
267 WM_CONVERTRESULT
268 WM_INTERIM
269 WM_IME_STARTCOMPOSITION
270 WM_IME_ENDCOMPOSITION
271 WM_IME_KEYLAST
271 WM_IME_COMPOSITION
272 WM_INITDIALOG
273 WM_COMMAND
274 WM_SYSCOMMAND
275 WM_TIMER
276 WM_HSCROLL
277 WM_VSCROLL
278 WM_INITMENU
279 WM_INITMENUPOPUP
287 WM_MENUSELECT
288 WM_MENUCHAR
289 WM_ENTERIDLE
290 WM_MENURBUTTONUP
291 WM_MENUDRAG
292 WM_MENUGETOBJECT
293 WM_UNINITMENUPOPUP
294 WM_MENUCOMMAND
295 WM_CHANGEUISTATE
296 WM_UPDATEUISTATE
297 WM_QUERYUISTATE
306 WM_CTLCOLORMSGBOX
307 WM_CTLCOLOREDIT
308 WM_CTLCOLORLISTBOX
309 WM_CTLCOLORBTN
310 WM_CTLCOLORDLG
311 WM_CTLCOLORSCROLLBAR
312 WM_CTLCOLORSTATIC
512 WM_MOUSEFIRST
512 WM_MOUSEMOVE
513 WM_LBUTTONDOWN
514 WM_LBUTTONUP
515 WM_LBUTTONDBLCLK
516 WM_RBUTTONDOWN
517 WM_RBUTTONUP
518 WM_RBUTTONDBLCLK
519 WM_MBUTTONDOWN
520 WM_MBUTTONUP
521 WM_MBUTTONDBLCLK
522 WM_MOUSEWHEEL
523 WM_XBUTTONDOWN
524 WM_XBUTTONUP
525 WM_MOUSELAST
525 WM_XBUTTONDBLCLK
526 WM_MOUSEHWHEEL
528 WM_PARENTNOTIFY
529 WM_ENTERMENULOOP
530 WM_EXITMENULOOP
531 WM_NEXTMENU
532 WM_SIZING
533 WM_CAPTURECHANGED
534 WM_MOVING
536 WM_POWERBROADCAST
537 WM_DEVICECHANGE
544 WM_MDICREATE
545 WM_MDIDESTROY
546 WM_MDIACTIVATE
547 WM_MDIRESTORE
548 WM_MDINEXT
549 WM_MDIMAXIMIZE
550 WM_MDITILE
551 WM_MDICASCADE
552 WM_MDIICONARRANGE
553 WM_MDIGETACTIVE
560 WM_MDISETMENU
561 WM_ENTERSIZEMOVE
562 WM_EXITSIZEMOVE
563 WM_DROPFILES
564 WM_MDIREFRESHMENU
640 WM_IME_REPORT
641 WM_IME_SETCONTEXT
642 WM_IME_NOTIFY
643 WM_IME_CONTROL
644 WM_IME_COMPOSITIONFULL
645 WM_IME_SELECT
646 WM_IME_CHAR
648 WM_IME_REQUEST
656 WM_IMEKEYDOWN
656 WM_IME_KEYDOWN
657 WM_IMEKEYUP
657 WM_IME_KEYUP
672 WM_NCMOUSEHOVER
673 WM_MOUSEHOVER
674 WM_NCMOUSELEAVE
675 WM_MOUSELEAVE
689 WM_WTSSESSION_CHANGE
704 WM_TABLET_FIRST
735 WM_TABLET_LAST
768 WM_CUT
769 WM_COPY
770 WM_PASTE
771 WM_CLEAR
772 WM_UNDO
773 WM_RENDERFORMAT
774 WM_RENDERALLFORMATS
775 WM_DESTROYCLIPBOARD
776 WM_DRAWCLIPBOARD
777 WM_PAINTCLIPBOARD
778 WM_VSCROLLCLIPBOARD
779 WM_SIZECLIPBOARD
780 WM_ASKCBFORMATNAME
781 WM_CHANGECBCHAIN
782 WM_HSCROLLCLIPBOARD
783 WM_QUERYNEWPALETTE
784 WM_PALETTEISCHANGING
785 WM_PALETTECHANGED
786 WM_HOTKEY
791 WM_PRINT
792 WM_PRINTCLIENT
793 WM_APPCOMMAND
794 WM_THEMECHANGED
797 WM_CLIPBOARDUPDATE
798 WM_DWMCOMPOSITIONCHANGED
799 WM_DWMNCRENDERINGCHANGED
800 WM_DWMCOLORIZATIONCOLORCHANGED
801 WM_DWMWINDOWMAXIMIZEDCHANGE
831 WM_GETTITLEBARINFOEX
856 WM_HANDHELDFIRST
863 WM_HANDHELDLAST
864 WM_AFXFIRST
895 WM_AFXLAST
896 WM_PENWINFIRST
911 WM_PENWINLAST
992 WM_DDE_FIRST
992 WM_DDE_INITIATE
993 WM_DDE_TERMINATE
994 WM_DDE_ADVISE
995 WM_DDE_UNADVISE
996 WM_DDE_ACK
997 WM_DDE_DATA
998 WM_DDE_REQUEST
999 WM_DDE_POKE
1000 WM_DDE_LAST
1000 WM_DDE_EXECUTE
1024 WM_CAP_START
1024 WM_USER
1024 WM_PSD_PAGESETUPDLG
1025 WM_CHOOSEFONT_GETLOGFONT
1025 WM_PSD_FULLPAGERECT
1025 WM_CAP_GET_CAPSTREAMPTR
1026 WM_PSD_MINMARGINRECT
1026 WM_CAP_SET_CALLBACK_ERRORA
1026 WM_CAP_SET_CALLBACK_ERROR
1027 WM_PSD_MARGINRECT
1027 WM_CAP_SET_CALLBACK_STATUS
1027 WM_CAP_SET_CALLBACK_STATUSA
1028 WM_CAP_SET_CALLBACK_YIELD
1028 WM_PSD_GREEKTEXTRECT
1029 WM_PSD_ENVSTAMPRECT
1029 WM_CAP_SET_CALLBACK_FRAME
1030 WM_CAP_SET_CALLBACK_VIDEOSTREAM
1030 WM_PSD_YAFULLPAGERECT
1031 WM_CAP_SET_CALLBACK_WAVESTREAM
1032 WM_CAP_GET_USER_DATA
1033 WM_CAP_SET_USER_DATA
1034 WM_CAP_DRIVER_CONNECT
1035 WM_CAP_DRIVER_DISCONNECT
1036 WM_CAP_DRIVER_GET_NAME
1036 WM_CAP_DRIVER_GET_NAMEA
1037 WM_CAP_DRIVER_GET_VERSION
1037 WM_CAP_DRIVER_GET_VERSIONA
1038 WM_CAP_DRIVER_GET_CAPS
1044 WM_CAP_FILE_SET_CAPTURE_FILE
1044 WM_CAP_FILE_SET_CAPTURE_FILEA
1045 WM_CAP_FILE_GET_CAPTURE_FILEA
1045 WM_CAP_FILE_GET_CAPTURE_FILE
1046 WM_CAP_FILE_ALLOCATE
1047 WM_CAP_FILE_SAVEASA
1047 WM_CAP_FILE_SAVEAS
1048 WM_CAP_FILE_SET_INFOCHUNK
1049 WM_CAP_FILE_SAVEDIB
1049 WM_CAP_FILE_SAVEDIBA
1054 WM_CAP_EDIT_COPY
1059 WM_CAP_SET_AUDIOFORMAT
1060 WM_CAP_GET_AUDIOFORMAT
1065 WM_CAP_DLG_VIDEOFORMAT
1066 WM_CAP_DLG_VIDEOSOURCE
1067 WM_CAP_DLG_VIDEODISPLAY
1068 WM_CAP_GET_VIDEOFORMAT
1069 WM_CAP_SET_VIDEOFORMAT
1070 WM_CAP_DLG_VIDEOCOMPRESSION
1074 WM_CAP_SET_PREVIEW
1075 WM_CAP_SET_OVERLAY
1076 WM_CAP_SET_PREVIEWRATE
1077 WM_CAP_SET_SCALE
1078 WM_CAP_GET_STATUS
1079 WM_CAP_SET_SCROLL
1084 WM_CAP_GRAB_FRAME
1085 WM_CAP_GRAB_FRAME_NOSTOP
1086 WM_CAP_SEQUENCE
1087 WM_CAP_SEQUENCE_NOFILE
1088 WM_CAP_SET_SEQUENCE_SETUP
1089 WM_CAP_GET_SEQUENCE_SETUP
1090 WM_CAP_SET_MCI_DEVICEA
1090 WM_CAP_SET_MCI_DEVICE
1091 WM_CAP_GET_MCI_DEVICEA
1091 WM_CAP_GET_MCI_DEVICE
1092 WM_CAP_STOP
1093 WM_CAP_ABORT
1094 WM_CAP_SINGLE_FRAME_OPEN
1095 WM_CAP_SINGLE_FRAME_CLOSE
1096 WM_CAP_SINGLE_FRAME
1104 WM_CAP_PAL_OPENA
1104 WM_CAP_PAL_OPEN
1105 WM_CAP_PAL_SAVE
1105 WM_CAP_PAL_SAVEA
1106 WM_CAP_PAL_PASTE
1107 WM_CAP_PAL_AUTOCREATE
1108 WM_CAP_PAL_MANUALCREATE
1109 WM_CAP_SET_CALLBACK_CAPCONTROL
1124 WM_CAP_UNICODE_START
1125 WM_CHOOSEFONT_SETLOGFONT
1126 WM_CHOOSEFONT_SETFLAGS
1126 WM_CAP_SET_CALLBACK_ERRORW
1127 WM_CAP_SET_CALLBACK_STATUSW
1136 WM_CAP_DRIVER_GET_NAMEW
1137 WM_CAP_DRIVER_GET_VERSIONW
1144 WM_CAP_FILE_SET_CAPTURE_FILEW
1145 WM_CAP_FILE_GET_CAPTURE_FILEW
1147 WM_CAP_FILE_SAVEASW
1149 WM_CAP_FILE_SAVEDIBW
1190 WM_CAP_SET_MCI_DEVICEW
1191 WM_CAP_GET_MCI_DEVICEW
1204 WM_CAP_PAL_OPENW
1205 WM_CAP_UNICODE_END
1205 WM_CAP_PAL_SAVEW
1205 WM_CAP_END
32768 WM_APP

OpenMP

ExpressバージョンのVCでも、Windows SDKから omp.h、ompassem.h、vcomp.lib、vcompd.lib を取ってくれば、OpenMPが使えるというのでやってみた。

#include <iostream>
#include <omp.h>

using namespace std;

int main() {
  #pragma omp parallel
  cout << "Hello OpenMP!" << endl;
  
  return 0;
}

コンパイル

cl /openmp hello.cpp

実行!

Hello OpenMP!Hello OpenMP!

さすが並列化・・・

inf

※VCの場合はfloat.hに_finiteがあることがわかった。

#include <iostream>
#include <cmath>

using namespace std;

int main() {
  cout << log10(0) << endl; // -inf
  cout << isinf(log10(0)) << endl; // 1
  cout << isfinite(log10(0)) << endl; // 0
  cout << (int)log10(0) << endl; // -2147483648
  cout << (unsigned int)log10(0) << endl; // 0
  
  return 0;
}