non vorrei lavorare

昔はおもにプログラミングやガジェット系、今は?

2019年第3四半期振り返り

こんばんは。長男は言われたら割と素直に実行にすぐ移す事が出来るようになって来たものの、次男が相変わらず屁理屈を言って、来年4月から小学生になれるのか心配な@kjunichiです。

7月

記事

8月

  • Noteに過去のN月M日をまとめた記事をNoteに投稿してた

note.mu

  • 長男のピアノとの手軽な共演を夢見て、コンパクトなMIDIキーボードを購入

KORG USB MIDIキーボード NANOKEY2 ナノキー 25鍵 ブラック

KORG USB MIDIキーボード NANOKEY2 ナノキー 25鍵 ブラック

iPhoneを音源に出来るケーブルがあった

記事

9月

  • Noteに過去のN月M日をまとめた記事を投稿してた
  • 高齢者の運転する車の不幸な事故が影響して、実家が停めていた俺の愛車を売り、衝突防止装置等が付いた 走りに期待できないミニバンに乗り換えることになり、ショックのあまり キャノンデールクロスバイクをかった。500万オーバーの移動手段から100分の1の価格の移動手段にw

クロスバイクはずいぶん前から狙っていたが、できればディスクブレーキモデルが ビジュアル的に欲しかったが、盗難の心配を考えるとなぁとなっていたところ、 たまたま長男の自転車を買いに行ったおしゃれ目の自転車屋さんで鮮やかなブルーで一目ぼれして 身長の低い自分向けのSサイズのフレームだったので衝動買い。

stravaなるサービスでサイクルコンピューターで取得したGPS情報等を共有でき、区間ごとのタイムの順位が出てきたり、 世の中の進歩を感じた。

ロードバイクではなく、街乗り寄りのクロスバイクなので、べダルの回転数とか不要で、デジタルコンパルがついてることのモデルが、 ちょうど自分の欲しいタイプだった。これにナビがあれば言うことなしだが、まぁそんなに遠出できそうにないので、 近場の走り易いコースが開拓できたら、ナビは不要になるという思いから低価格モデルを選択。

BRYTON(ブライトン) GPSサイクルコンピューター Rider15E ブラック

BRYTON(ブライトン) GPSサイクルコンピューター Rider15E ブラック

IT関連では、ElectronアプリのKeycastjsの更新を試みる中、NodObjCが不安定で使えないこと、また、ffiの後継版的な N-APIに対応したffi-napiモジュールはNodObjCに必要な機能を実装しなさそうな様子なのを踏まえて、ffi-napiでPythonと連携させ、 Python側でPyObjC経由でCocoa APIを叩いて、これと連携させる方向で進めようとしている。

記事

関連記事

10年前の記事

6年前の記事

2年前の記事

NAPI版のnode-ffi-napiを使ってNode.jsからPythonを動かす

こんばんは。夜遅くまで子供達が起きてしまい、朝叩き起こしてもなかなか起きない悩みが一向に解決しない@kjunichiです。

背景

たまーに、流行のGitHub見て転職案内してくれるサイトに登録してるので、 KeyCast.js見ました!なんてメールをいただくことがありますが。 AIからのメールなのはバレバレでもメンタル豆腐なので、この数年メンテしておらず心苦しくになることがあるので、 重い腰を上げて対応しようとしたら、NodObjCが不安定すぎて、別の方法を模索している際のメモ。

NodObjCの代わりにPyObjcを使ってみるための準備

NodObjCがN-API版のnode-ffi-napiではサポートされていない模様。 しかし、node-ffi-napiから直接libobjcを叩く際にはBlocksを引数にとるCocoa APIの扱いが不明なので、 PyObjCを使って回避を試みる。

ffi-napiを使ってNode.jsからPythonを動かした

const ffi = require('ffi-napi')
const ref = require('ref-napi')

const voidPtr = ref.refType(ref.types.void);

const libpython2 = ffi.Library('libpython2.7', {
'Py_SetProgramName': [ 'void',  [voidPtr] ],
'Py_Initialize': [ 'void',  [] ],
'PyRun_SimpleString': [ 'int',  ['string'] ],
'Py_Finalize': [ 'void',  [] ]
})

libpython2.Py_SetProgramName(null)
libpython2.Py_Initialize()
const pyscript = `print("Hello world!\\n")`
libpython2.PyRun_SimpleString(pyscript)
libpython2.Py_Finalize()

Node.jsでスレッドを作り、Pythonを動かす

Node.jsとPythonとのやり取りはHTTP越しで行うことを考えている。 Node.jsに限らず、FFIスクリプト系言語で行った方ならCのヘッダの関数や構造体の型定義をちまちま書く作業の 手間を想像することはたやすいかと思われる。

Node.js側でPythonスクリプトを起動するだけして、その後のやり取りはHTTP越しに行うことにすれば、Pythonの処理系にPIPで 追加モジュールのインストールの必要もなく、Node.js側も標準のモジュールで通信が行える。

ワーカ用のJavaScriptコード

const ffi = require('ffi-napi')
const ref = require('ref-napi')

const voidPtr = ref.refType(ref.types.void);

const libpython2 = ffi.Library('libpython2.7', {
'Py_SetProgramName': [ 'void',  [voidPtr] ],
'Py_Initialize': [ 'void',  [] ],
'PyRun_SimpleString': [ 'int',  ['string'] ],
'Py_Finalize': [ 'void',  [] ]
})

libpython2.Py_SetProgramName(null)
libpython2.Py_Initialize()
const pyscript = `str=raw_input()\nprint("Hello world!\\n")`
libpython2.PyRun_SimpleString(pyscript)
libpython2.Py_Finalize()

メインスレッド用のJavaScriptコード

const { Worker, isMainThread, workerData } = require('worker_threads')
const { resolve } = require('path')

let current = 0

const counter = (title, cnt) => {
    console.log(`| ${title} |: ${cnt}`)
}

if (isMainThread) {
    console.log('Main Thread')

        for (let i = 0; i < 1; i++) {
            // 相対パスはダメ
            // この場合(__filename)はworkerも同じこのファイルを参照する
            // 第二引数はグローバルパラメーター
            new Worker(resolve("python.js"), { workerData: i })
        }

    setInterval((title) => {
            counter(title, ++current)
            }, 1000, 'MainThread')
} else {
    console.log(`worker: ${workerData}`)

        setInterval((title) => {
                counter(title, ++current)
                }, 1000, `worker: ${workerData}`)
}

実行結果

youtu.be

おわりに

背景で触れたようにCocoa専用なので、今度のCatalinaではPythonが標準で入らなくなる模様。 しかしながら、Node.jsはいまでも確かPython2系が必要なはずで、今回のアプローチでも Catalina環境でもNode.jsを利用する場合、Pythonを入れる必要があり、無駄にはならないと思われる。

参考資料

blog.hiroppy.me

関連記事

8年前の記事

5年前の記事

go modulesでSocket.ioからWebSocketに移行せずに済んだ件

こんにちは。次男も来年からは夏休みに宿題がありますが、奥さんが、前年の長男の自由研究を行えば、良いじゃね?って言ってます。そんな訳で、長男はあとは大きな課題は交通安全ポスターです。あおり運転ネタとか思いつきますが、学校に提出するので自粛かなw@kjunichiです。

背景

goのデスクトップマスコットgopheronでちょっと前からSocket.io互換のモジュールを最新版を利用すると ビルドエラーとなってしまう状態だった。

しかも、最新版のGo版のsocket.ioの互換ライブラリがブロードキャストに対応しなくなってしまったので、 この機会に勉強もかねて、素のWebSocketでの実装に移行しようかと考えていた。

goの新しいモジュール管理方式

npmやmrubyでは依存するライブラリのブランチ等を指定することができ、この問題は回避できていた。 が、goはバージョンを指定することができず、昔から、あれこれ回避する方法が考えられていたものの、 決定打はなかった模様。。。

gopheronでの対応

GO111MODULE=on go mod init

go.moduleというファイルを作成して、これに以下の内容を記述

module github.com/kjunichi/gopheron

go 1.12

require github.com/googollee/go-socket.io v1.0.1

おわりに

go modulesを知って、当面は以前の版を指定することで、この問題を回避できた。

関連記事

7年前の記事