Windows の Rust で go の関数を呼ぶ

GoでRustを呼ぶ。そしてRustでGoを呼ぶ。https://qiita.com/momotaro98/items/92e39e214b0e92f454a7

こちらを参考にさせて頂いたが Windows の場合 go の -buildmode=c-archive で作られる lib が mingw 用なり Windows の Rust が使う MSVC 用と合わないので DLL にして回避した。(具体的には crt の関数がないエラーとセクションの形式が合っていないような警告でリンクできない)

細かい事は省くが x64 の msys2 環境で go も Rust もインストール済みの場合の例です。

main.go

package main

import "C"

//export GoFunc1
func GoFunc1(name string) *C.char {
	str := name + " ʕ ◔ϖ◔ʔ"
	return C.CString(str)
}

func main() {}

go のソースコードから "gofuncs.dll" という名前の dll を作る

go build -buildmode=c-shared -o gofuncs.dll ./main.go

dll で公開している関数を記述した def ファイルを作る (TODO: 自動化, dumpbin.exe からできるはず)

gofuncs.def

LIBRARY   gofuncs
EXPORTS
   GoFunc1 @1

lib.exe で DLL からインポートライブラリを作成する

LIBEXE=`cygpath --unix "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC/14.32.31326\bin\Hostx64\x64\lib.exe"`
"$LIBEXE" /def:gofuncs.def /out:gofuncs.lib /machine:x64

これでインポートライブラリ gofuncs.lib (MSVC 形式) が作成される

Rust のソースファイル

use std::ffi::{CStr, CString};
use std::os::raw::c_char;

extern "C" {
	fn GoFunc1(name: GoString) -> *const c_char;
}

#[repr(C)]
struct GoString {
	ptr: *const c_char,
	len: i64,
}

fn main() {
	let src_str = CString::new("I'm a Rustacean").expect("CString::new failed");
	let ptr = src_str.as_ptr();
	let param = GoString {
		ptr: ptr,
		len: src_str.as_bytes().len() as i64,
	};
	
	let go_func_result = unsafe { GoFunc1(param) };
	let c_str = unsafe { CStr::from_ptr(go_func_result) };
	let result = c_str.to_str().expect("to_str failed");
	println!("{}", result);
}

cargo でリンクするライブラリを指定

build.rs
fn main() {
	let dir = std::env::var("PWD").unwrap();
	println!("cargo:rustc-link-search={}", std::path::Path::new(&dir).display());
	println!("cargo:rustc-link-lib=gofuncs");
}

これで cargo run すると "I'm a Rustacean ʕ ◔ϖ◔ʔ" と表示される。

Linux Mint Cinnamon に Windows から Chrome Remote Desktop する

がっつりハマった。
やたら解像度が高くて文字がつぶれて見えないんですよ。
あ、最初の画面は Software rendering を選ぶといいと思います。これを選ばないと右上に「ハードウェアレンダリングできないンゴ」みたいな警告も出ます。
この接続直後に出る設定は /usr/share/xsessions/*.desktop みたいなファイルになってるんですが、これらのファイルは触る必要なかった。
次に /opt/google/chrome-remote-desktop/chrome-remote-desktop というファイルなんですが、これが pythonスクリプトChrome Remote Desktop を待ち受けるサービスを起動/停止してくれます。これも中身は弄る必要なかった(けど何が設定できるのかはわかるので読んでみてもいい)。
この起動スクリプトを読めば、.profile に CHROME_REMOTE_DESKTOP_DEFAULT_DESKTOP_SIZES を設定すればいい事がわかります。
なので .bash_profile で設定しました。
(Nemo で隠しファイルが見えないのは Ctrl+H でトグルできる)

# my .bash_profile

# include .profile if it exists (WARNING: recursive source)
if [ -f "$HOME/.profile" ]; then
    . "$HOME/.profile"
fi

export CHROME_REMOTE_DESKTOP_DEFAULT_DESKTOP_SIZES="1024x768,1280x1024,1680x1050"

これで端末から

sudo login YOUR_NAME

した後に

env | grep CHROME

で書いた設定がでる状態になれば OK (最初横着して起動スクリプトを叩く端末で export してたけどこれじゃ駄目だった。ちゃんと .profile 辺りに書く必要がある。

と思ったけど再起動したら端末立ち上がらなくなったわ……。多分 .profile を読もうとするのが本当にダメなんだと思う。諦めて .profile に export 追記したら直った。

OS を再起動してもいけるけど、さらっと確認したかったら

/opt/google/chrome-remote-desktop/chrome-remote-desktop --stop
/opt/google/chrome-remote-desktop/chrome-remote-desktop --start

したら想定した解像度でつながるようになった。めでたしめでたし。ではなくてもう一つはまったのがキーボードの設定。Windows が日本語キーボードだから記号が打てなかった。
左下の Linux Mint ボタン(っていう名前だよね? ホバーで Menu って出るけど)から Preferences -> Keyboard -> Layouts の左側の一覧に Japanese を追加, English の優先順位を下げても思った通りにならなかったので English は削除したら意図したとおりになった。
これでだいたい大丈夫か? (なおクリップボード共有も効いてるのでいい感じ)

 

Time Capsule 用SSDの載せ替えメモ

ほぼ Time Capsule として使用している Mac miniSSD が満杯になったと警告がきたので大きな SSD にデータを移行しつつ載せ替える作業のメモのつもりだった。

そんなに簡単に事は運ばなかったので後日に続きます。

前提としてこの Mac mini (Mid 2011)は元々は1ドライヴしか付いてなくて内蔵ドライヴ増設キット的なマウンターで2ドライヴ目を増設していたはず(薄い記憶)。

まず新しい 2.5 inch SSD と USB 接続の外付けドライヴ化ケースを用意しました。

こちらで旧データを移行してから、ドライヴを載せ替える想定です。

新しいドライヴを USB 接続すると「このドライヴはこの Mac では読めない。イジェクトする?」という警告が表示されるのでキャンセルして Disk Utility の画面を開きます。

Disk Utility に外付けのドライヴが認識されているはずなので、Erase ボタンを押して、名前とフォーマットの類いを選びます。

今回はフォーマットには Mac OS Extended (Journaled) を、パーティションタイプには GUID パーティションを選択しました。

ドライヴ名には空白を含めないのがおススメです(今回自分は TimeCapsuleSSD という名前にしました。/Volume 以下にこの名前で入るので、絶対空白なんか入れないほうがいいです。旧ドライヴは謎のノリで "Macintosh SSD" という名前にしちゃったのですが、シェル上から扱う時に何かと気持ち悪いですよね。全体をクォーテーションしてたのにパス補完するだけでエスケープに書き換えられたりする辺りとかが)

割とすぐにフォーマットは終ります。今回はパーティションを区切るつもりがないので1個の大きなパーティションのままでいきます。

ここまででドライヴとしての利用は可能になったので、次にデータ移行に移ろうと考えました。

まず現状のサービスを一旦止めようと思いました。

自分が Mac mini を Time Capsule 相当に設定した当時はこの機能は Server アプリの機能だったのですが、High Sierra 辺りで Server アプリを購入しなくても利用できるようになったようで、数日前にこの老骨がサポートしてる限界でもあった High Sierra にアップグレードした結果、設定場所が全然わかりません(Server アプリからは設定個所が消えています)。

どうやら新規設定する場合、共有の設定のファイル共有から Time Machine バックアップ先として設定できるようなのですが、現時点ではそういう設定がされていない模様。

そして新しい設定方法だと SMB 共有からでも TimeCapsule 用のドライヴが無駄に表示されるのなんか嫌だなぁと思って、旧設定みたいに共有ドライヴとしては見えないようにできないかなと思ったのですが、全然わからなかったので諦めて、共有として見える設定でいく事にします(ドライヴ名をそれっぽくして本当によかった)。

じゃあデータ移行だなーと思って、ちょっとググった結果

cp -a ならシンボリックリンク辿らずにコピーできる的な記述をみたので cp -a して1.5日~2日程度放置、「やっぱり USB 2 だから遅いのかなー」とか思いながら待っていたのですが

嘘じゃん

がっつりシンボリックリンク辿った結果、2TB まるまる埋め尽くしてコピーが終わりました…… orz

※後日追記 嘘じゃないかも。単純に新しい SSD もバックアップ対象に含まれてただけかも?

(そもそも更に新しいバージョンの macOS だとこの cp するまでになんか権限設定要るらしい。High Sierra ではそこは問題にならなかった)

わかったよ、わかったパトラッシュ、素直に dd して、後からパーティションを広げればいいんだね。そうするよ。と思ったあたりが今。

Draft として放置してたこの記事を一旦 publish してしまおうと決断した辺りになります。

あと最初はデータ移行が終わったら内蔵のドライヴと入れ替えるつもりだったけど、ここでこんなに手間取ってるのと

「別にバックアップ用のドライヴは USB 2 経由でも問題ないのでは?」

と思い始めたので、外付けのまま運用でいいような気がしてきた。

本体と密着させた状態で放置だと無駄に熱がこもると思うので、それだけなんとかすればむしろ外付けの状態の方がメンテが楽じゃんね?

 

Mac で sudo する為には root ユーザーの有効化が必要

Mac で sudo する為には自身が admin に所属しているだけではダメで root ユーザーを有効にしなくてはいけないらしい。(あと管理者でも wheel グループには所属していない)

Mac で root を有効にする
https://support.apple.com/en-us/HT204012
https://support.apple.com/ja-jp/HT204012

System Preferences -> Users & Groups -> (Unlock) -> Login Options -> Network Account Server: Join... -> Open Directory Utility... -> (Unlock on Directory Utility) -> Edit of Menu bar -> Enable Root User
尚ここで設定するのは root のパスワードなので, 普段 sudo する時に使う自分のパスワードとは違う。
多少入力しづらい物でも問題ないと思う。

ファイル名に使うと問題がある文字の備忘録

ディレクトリ名の一部に @ を使ってると MSYS2 64 bit のインストーラーに

The installation path must not contain "@".

と怒られる。

今できるだけローカル PC には何も保存しないように試みていて、NAS 内にインストールしたかったのだけど、まず MSYS2 のインストーラーはネットワークドライブのパスを受け付けなかったので、仕方がなくドライブレターにマップする事にした。

そしたらネットワークドライブの直下はマップできなくて、仕方がなく一階層入ったディレクトリをマップした。

最後に上記の通りディレクトリ名に @ を含んでいたから更に奥の階層でマッピングしなおすことになった。

 

ネットワークドライブを C: 内のどこかにマウントできたらいいんだけど。

Mac は使いづらくて好きじゃないけど、最近本当に Windows もなんでこんなに不便なんだろうって思う。いや、今さら MSYS なのかって感じだろうけど、"Developper! Developper! Developper!" って叫んで発表された WSL がストア経由でディストリビューションを取得するような仕組みだったりするのも本当に嫌。

MacWindows も嫌なら、次は Chromebook に行くしかないのかね?(まともなデスクトップ Linux っていうのは何度も夢を見てるけどやっぱり幻想だし)

 

追記: この方法でセットアップしたら全ての動作がありえないくらい重い。やっぱり NTFS 前提なのかもしれない。

まく使いの憂鬱(Karabiner-Elements)の設定ファイル

何度も備忘録として見に来るけど、旧 Karabinerの設定しか書いてなくて毎回凹むので Karabiner-Elements の設定を残しておく。
json は自分で beautify して欲しい(自分には標準的な json のインデントは受け入れられない)。
主に PC 用キーボードを繋いで Windows 風に使いたい人向けの設定のつもり。

追記: ここに書いておくより gist に置いておくほうが参照しやすいかもと思ったので gist に置いた。
今後も追記しそうだけど修正するのは gist 側だけになるかも。
some PC-esque settings for Karabiner Elements · GitHub

追記2: 結局1ファイルに収まらなくなってきてファイルを分割した。
もう gist の方を見てもらうしかない。

Apple の日本語キーボードの場合だけ Control を Command 扱いと、Caps Lock を Ctrl 扱いにする。Apple の日本語キーボード以外では Caps Lock を Command 扱いにする。ProductID で JIS キーボードかどうか区別できてない気もするし、手持ちの2個だけなので自分の環境の ProductID に上手い事書き換えて下さい。

{
    "title": "karabiner - around Ctrl and Command-key settings",
    "rules":
    [
        {
            "description": "change left-Control(⌃) to left-Command(⌘) on Apple JIS keyboards",
            "manipulators":
            [
                {
                    "type": "basic",
                    "from":
                    {
                        "key_code": "left_control",
                        "modifiers": {"optional": "any"}
                    },
                    "to":
                    [
                        {
                            "key_code": "left_command"
                        }
                    ],
                    "conditions":
                    [
                        {
                            "type": "device_if",
                            "identifiers":
                            [
                                {
                                    "vendor_id": 1452,
                                    "product_id": 633,
                                    "description": "Apple Internal Keyboard (MacBook (Retina, 12-inch, 2017))"
                                },
                                {
                                    "vendor_id": 1452,
                                    "product_id": 656,
                                    "description": "Apple Internal Keyboard (MacBook Air (11-inch, Early 2014))"
                                }
                            ]
                        }
                    ]
                }
            ]
        },
        {
            "description": "change Caps-lock(⇪) to left-Control(⌃) on Apple JIS keyboards",
            "manipulators":
            [
                {
                    "type": "basic",
                    "from":
                    {
                        "key_code": "caps_lock",
                        "modifiers": {"optional": "any"}
                    },
                    "to":
                    [
                        {
                            "key_code": "left_control"
                        }
                    ],
                    "conditions":
                    [
                        {
                            "type": "device_if",
                            "identifiers":
                            [
                                {
                                    "vendor_id": 1452,
                                    "product_id": 633,
                                    "description": "Apple Internal Keyboard (MacBook (Retina, 12-inch, 2017))"
                                },
                                {
                                    "vendor_id": 1452,
                                    "product_id": 656,
                                    "description": "Apple Internal Keyboard (MacBook Air (11-inch, Early 2014))"
                                }
                            ]
                        }
                    ]
                }
            ]
        },
        {
            "description": "change Caps-lock(⇪) to left-Command(⌘) on non-Apple JIS keyboard",
            "manipulators":
            [
                {
                    "type": "basic",
                    "from":
                    {
                        "key_code": "caps_lock",
                        "modifiers": {"optional": "any"}
                    },
                    "to":
                    [
                        {
                            "key_code": "left_command"
                        }
                    ],
                    "conditions":
                    [
                        {
                            "type": "device_unless",
                            "identifiers":
                            [
                                {
                                    "vendor_id": 1452,
                                    "product_id": 633,
                                    "description": "Apple Internal Keyboard (MacBook (Retina, 12-inch, 2017))"
                                },
                                {
                                    "vendor_id": 1452,
                                    "product_id": 656,
                                    "description": "Apple Internal Keyboard (MacBook Air (11-inch, Early 2014))"
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

Home と End がありえない挙動をするので、こちらの望む挙動に変更。

{
    "title": "Karabiner - functional keys settings",
    "rules":
    [
        {
            "description": "change Home(↖) to Command(⌘) + left-arrow",
            "manipulators":
            [
                {
                    "type": "basic",
                    "from":
                    {
                        "key_code": "home",
                        "modifiers": {"optional": "any"}
                    },
                    "to":
                    [
                        {
                            "key_code": "left_arrow",
                            "modifiers": "command"
                        }
                    ]
                }
            ]
        },
        {
            "description": "change End(↘) to Command(⌘) + right-arrow",
            "manipulators":
            [
                {
                    "type": "basic",
                    "from":
                    {
                        "key_code": "end",
                        "modifiers": {"optional": "any"}
                    },
                    "to":
                    [
                        {
                            "key_code": "right_arrow",
                            "modifiers": "command"
                        }
                    ]
                }
            ]
        }
    ]
}

古き良き XFER と NFER (いやこれPC-98での名前だろ、俺はPC-98から入ったから好きだが)を英数とかなに置き換えるのと、
バックスラッシュ周りで要らん事しやがるのを回避。この Apple の愚行は MS が日本語フォントのバックスラッシュを円記号のグリフにしてるのと同じ程度の愚行だと思う。
誰得なのか3秒程度考える知恵があったらこんな仕様にならないだろ。

{
    "title": "Karabiner - Japanese keyboard settings",
    "rules":
    [
        {
            "description": "change Yen-sign(\u00a5) to Backslash(\\)",
            "manipulators":
            [
                {
                    "type": "basic",
                    "from":
                    {
                        "key_code": "international3"
                    },
                    "to":
                    [
                        {
                            "key_code": "international3",
                            "modifiers": "option"
                        }
                    ]
                }
            ]
        },
        {
            "description": "change Option(⌥) + Yen-sign(\u00a5) to Yen-sign(\u00a5)",
            "manipulators":
            [
                {
                    "type": "basic",
                    "from":
                    {
                        "key_code": "international3",
                        "modifiers":
                        {
                            "mandatory": "option"
                        }
                    },
                    "to":
                    [
                        {
                            "key_code": "international3"
                        }
                    ]
                }
            ]
        },
        {
            "description": "change nfer(\u7121\u5909\u63db) to eisuu(\u82f1\u6570)",
            "manipulators":
            [
                {
                    "type": "basic",
                    "from":
                    {
                        "key_code": "japanese_pc_nfer",
                        "modifiers": {"optional": "any"}
                    },
                    "to":
                    [
                        {
                            "key_code": "japanese_eisuu"
                        }
                    ]
                }
            ]
        },
        {
            "description": "change xfer(\u5909\u63db) to kana(\u304b\u306a)",
            "manipulators":
            [
                {
                    "type": "basic",
                    "from":
                    {
                        "key_code": "japanese_pc_xfer",
                        "modifiers": {"optional": "any"}
                    },
                    "to":
                    [
                        {
                            "key_code": "japanese_kana"
                        }
                    ]
                }
            ]
        }
    ]
}

これは完全にアプリ単位での処理

{
    "title": "Karabiner - Windows-esque style settings",
    "rules":
    [
        {
            "description": "open Developer Tools/Web Inspector with Ctrl+Shift+I in Chrome/Safari/Firefox/Vivaldi",
            "manipulators":
            [
                {
                    "type": "basic",
                    "from":
                    {
                        "key_code": "i",
                        "modifiers":
                        {
                            "mandatory": ["left_command", "shift"]
                        }
                    },
                    "to":
                    [
                        {
                            "key_code": "i",
                            "modifiers": ["option", "left_command"]
                        }
                    ],
                    "conditions":
                    [
                        {
                            "type": "frontmost_application_if",
                            "bundle_identifiers":
                            [
                                "^com\\.google\\.Chrome$",
                                "^com\\.google\\.Chrome.canary$",
                                "^com\\.google\\.Chrome.beta$",
                                "^com\\.google\\.Chrome.dev$",
                                "^org\\.chromium\\.Chromium$",
                                "^org\\.mozilla\\.firefox$",
                                "^com\\.vivaldi\\.Vivaldi$"
                            ]
                        }
                    ]
                }
            ]
        },
        {
            "description": "move file to trash with Delete on finder",
            "manipulators":
            [
                {
                    "type": "basic",
                    "from":
                    {
                        "key_code": "delete_forward"
                    },
                    "to":
                    [
                        {
                            "key_code": "delete_or_backspace",
                            "modifiers": ["left_command"]
                        }
                    ],
                    "conditions":
                    [
                        {
                            "type": "frontmost_application_if",
                            "bundle_identifiers": ["^com\\.apple\\.finder$"]
                        }
                    ]
                }
            ]
        },
        {
            "description": "delete file immediately with Shift+Delete on finder",
            "manipulators":
            [
                {
                    "type": "basic",
                    "from":
                    {
                        "key_code": "delete_forward",
                        "modifiers":
                        {
                            "mandatory": ["shift"]
                        }
                    },
                    "to":
                    [
                        {
                            "key_code": "delete_or_backspace",
                            "modifiers": ["option", "left_command"]
                        }
                    ],
                    "conditions":
                    [
                        {
                            "type": "frontmost_application_if",
                            "bundle_identifiers": ["^com\\.apple\\.finder$"]
                        }
                    ]
                }
            ]
        }
    ]
}

これは適用しなくていいです。UK キーボード(US じゃない UK だ)で日本語どうやって入力すんだよ!と思って調べた知識の確認なので。
もしこっちを使いたかったら上の英数とかなへの変換の方を適用しないでおく。

{
    "title": "Karabiner - additional settings for compatibility",
    "rules":
    [
        {
            "description": "change nfer(\u7121\u5909\u63db) to Option(⌥) + Shift(⇧) + S",
            "manipulators":
            [
                {
                    "type": "basic",
                    "from":
                    {
                        "key_code": "japanese_pc_nfer",
                        "modifiers": {"optional": "any"}
                    },
                    "to":
                    [
                        {
                            "key_code": "s",
                            "modifiers": ["option", "left_shift"]
                        }
                    ]
                }
            ]
        },
        {
            "description": "change xfer(\u5909\u63db) to Option(⌥) + Shift(⇧) + Z",
            "manipulators":
            [
                {
                    "type": "basic",
                    "from":
                    {
                        "key_code": "japanese_pc_xfer",
                        "modifiers": {"optional": "any"}
                    },
                    "to":
                    [
                        {
                            "key_code": "z",
                            "modifiers": ["option", "left_shift"]
                        }
                    ]
                }
            ]
        }
    ]
}

まく使いの憂鬱(Karabiner-Elements)の設定ファイル

何度も備忘録として見に来るけど、旧 Karabinerの設定しか書いてなくて毎回凹むので Karabiner-Elements の設定を残しておく。
json は自分で beautify して欲しい(自分には標準的な json のインデントは受け入れられない)。
主に PC 用キーボードを繋いで Windows 風に使いたい人向けの設定のつもり。

{
    "title": "My Settings",
    "rules":
    [
        {
            "description": "Change left-Control(⌃) to left-Command(⌘)",
            "manipulators":
            [
                {
                    "type": "basic",
                    "from":
                    {
                        "key_code": "left_control",
                        "modifiers": {"optional": "any"}
                    },
                    "to":
                    [
                        {
                            "key_code": "left_command"
                        }
                    ]
                }
            ]
        },
        {
            "description": "Change Caps-lock(⇪) to left-Control(⌃) anyway",
            "manipulators":
            [
                {
                    "type": "basic",
                    "from":
                    {
                        "key_code": "caps_lock",
                        "modifiers": {"optional": "any"}
                    },
                    "to":
                    [
                        {
                            "key_code": "left_command"
                        }
                    ]
                }
            ]
        },
        {
            "description": "Change Home(↖) to Command(⌘) + left-arrow",
            "manipulators":
            [
                {
                    "type": "basic",
                    "from":
                    {
                        "key_code": "home",
                        "modifiers": {"optional": ["any"]}
                    },
                    "to":
                    [
                        {
                            "key_code": "left_arrow",
                            "modifiers": "command"
                        }
                    ]
                }
            ]
        },
        {
            "description": "Change End(↘) to Command(⌘) + right-arrow",
            "manipulators":
            [
                {
                    "type": "basic",
                    "from":
                    {
                        "key_code": "end",
                        "modifiers": {"optional": ["any"]}
                    },
                    "to":
                    [
                        {
                            "key_code": "right_arrow",
                            "modifiers": "command"
                        }
                    ]
                }
            ]
        },
        {
            "description": "Change Yen-sign(¥) to Backslash(\\)",
            "manipulators":
            [
                {
                    "type": "basic",
                    "from":
                    {
                        "key_code": "international3"
                    },
                    "to":
                    [
                        {
                            "key_code": "international3",
                            "modifiers": "option"
                        }
                    ]
                }
            ]
        },
        {
            "description": "Change Option(⌥)+Yen-sign(¥) to Yen-sign(¥)",
            "manipulators":
            [
                {
                    "type": "basic",
                    "from":
                    {
                        "key_code": "international3",
                        "modifiers":
                        {
                            "mandatory": "option"
                        }
                    },
                    "to":
                    [
                        {
                            "key_code": "international3"
                        }
                    ]
                }
            ]
        }
    ]
}