msys2、emacs(x64) 再インストール
msys2インストール
MSYS2 Wikiにて、msys2-x86_64-20150512.exe を取得し、インストールを実行します。
更新
- シェル(C:/MSYS64/mingw64_shell.bat)を起動します。
- pacman -Sy
- リポジトリ->データベース更新
- pacman --needed -S bash pacman pacman-mirrors msys2-runtime
- 一旦シェルを終了し、再度シェルを起動します。
- 前段の更新したパッケージが使用中となるので、一旦シェルを終了させる必要があります(と書いてあるような...)。
- pacman -Su
- 残りの全パッケージの更新を行います。
あとは、お好きなパッケージをpacmanで取得、インストールします。
bash here
レジストリに直接設定します。昔作ったものが元になっているので、紆余曲折したままごまかしながら使ってます。
- bash_here.reg
Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\Directory\shell\shell] @="mintty here [selected](&B)" [HKEY_CLASSES_ROOT\Directory\shell\shell\command] @="C:\\msys64\\usr\\bin\\mintty.exe -i /msys2.ico /usr/bin/bash -lc 'cd \"%V\"; export CHERE_INVOKING=1; export MSYSTEM=MINGW64; export MSYSCON=mintty.exe; exec bash --login -i'" [HKEY_CLASSES_ROOT\Directory\shell\shell_sudo] @="mintty sudo [selected](&B)" [HKEY_CLASSES_ROOT\Directory\shell\shell_sudo\command] @="C:\\msys64\\usr\\bin\\mintty_SUDO.exe -i /msys2.ico /usr/bin/bash -lc 'cd \"%V\"; export CHERE_INVOKING=1; export MSYSTEM=MINGW64; export MSYSCON=mintty_SUDO.exe; exec bash --login -i'" [HKEY_CLASSES_ROOT\Directory\Background\shell\shell] @="mintty here(&B)" [HKEY_CLASSES_ROOT\Directory\Background\shell\shell\command] @="C:\\msys64\\usr\\bin\\mintty.exe -i /msys2.ico /usr/bin/bash -lc 'cd \"%V\"; export CHERE_INVOKING=1; export MSYSTEM=MINGW64; export MSYSCON=mintty.exe; exec bash --login -i'" [HKEY_CLASSES_ROOT\Directory\Background\shell\shell_sudo] @="mintty sudo(&B)" [HKEY_CLASSES_ROOT\Directory\Background\shell\shell_sudo\command] @="C:\\msys64\\usr\\bin\\mintty_SUDO.exe -i /msys2.ico /usr/bin/bash -lc 'cd \"%V\"; export CHERE_INVOKING=1; export MSYSTEM=MINGW64; export MSYSCON=mintty_SUDO.exe; exec bash --login -i'"
emacs再インストール
インストール
chuntaroさんのx64バイナリを使います。emacs-24.5-IME-patched.zip
をダウンロードして展開、そのまま使えます。今回は、C:\utilities\emacs -> C:\utilities\emacs-24.5-IME-patched とシンボリックリンクを張るような配置にしました。
関連付け
emacsの再インストールでいっつも引っかかるのが、拡張子の関連付け、規定のプログラム指定などがうまくいかなくなることです。毎度、引っかかります。
- [スタート]->[規定のプログラム]
- ファイル選択 [右クリ]->[プロパティ]->[プログラム:変更]
- ファイル選択 [右クリ]->[プログラムから開く...]
などで、再インストールしたrunemacs.exeが登録できません。エクスプローラで新しいrunemacs.exeを選択しても、プログラムとして認識されなくなるのです。
解決策は、レジストリで次の項目を削除するです。
Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\Applications\runemacs.exe] [HKEY_CLASSES_ROOT\Applications\runemacs.exe\shell] [HKEY_CLASSES_ROOT\Applications\runemacs.exe\shell\open] [HKEY_CLASSES_ROOT\Applications\runemacs.exe\shell\open\command] @="\"C:\\Program Files\\GNU\\Emacs23\\bin\\runemacs.exe\" \"%1\""
古い設定が残っていて、新しいrunemacs.exeが空振りしているようです。HKEY_CLASSES_ROOT\Applications\runemacs.exeのツリーを削除しました。あとは、通常の関連付けができるようになります。あっ、システムが壊れても責任取りませんから。
次のURLを参照して下さい。
electron on VS2013
Electronのfirst Electron appをビルド、実行します。
- electron-prebuilt@0.28.3
- Visual Studio Community 2013
- (node.js@0.12.3)
package.json を作成
(package.json自体はVSが生成してくれてるので、中身を書き換えます。)
(tutorialでは、main.jsですが、app.jsにしました(なっちゃいました、してしまいました)。)
{ "name" : "your-app", "version" : "0.1.0", "main" : "app.js" }
app.ts を作成
(app.ts自体はVSが生成してくれるので、中身を書き換えます。)
var app = require('app'); // Module to control application life. var BrowserWindow = require('browser-window'); // Module to create native browser window. // Report crashes to our server. require('crash-reporter').start(); // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the javascript object is GCed. var mainWindow = null; // Quit when all windows are closed. app.on('window-all-closed', function () { if (process.platform != 'darwin') { app.quit(); } }); // This method will be called when Electron has done everything // initialization and ready for creating browser windows. app.on('ready', function () { // Create the browser window. mainWindow = new BrowserWindow({ width: 800, height: 600 }); // and load the index.html of the app. mainWindow.loadUrl('file://' + __dirname + '/index.html'); // Open the devtools. mainWindow.openDevTools(); // Emitted when the window is closed. mainWindow.on('closed', function () { // Dereference the window object, usually you would store windows // in an array if your app supports multi windows, this is the time // when you should delete the corresponding element. mainWindow = null; }); });
index.html
(新規に作成保存しました。)
<!DOCTYPE html> <html> <head> <title>Hello World!</title> </head> <body> <h1>Hello World!</h1> We are using io.js <script>document.write(process.version)</script> and Electron <script>document.write(process.versions['electron'])</script>. </body> </html>
補足
iojs.exe が動いている?node.jsと同梱されてるのとは版が違うし...electron-prebuiltは、でかいです。npmでインストールしたらダウンロードで10分程度掛かる大きさです。このサイズなら何が入っててもおかしくない。io.js/node.jsの相違が現れるまで追求しません。
node-ffi char**
node-ffiを使って、JavaScriptからC++ DLL内で作成したchar*にアクセスする方法です。
- Win7 64bit
- Visual Studio Community 2013
- node.js@0.12.3
- node-ffi@1.3.1
- ref@1.0.2
C++でバッファを確保して、JavaScriptで受け取ります。JavaScriptで利用するとか、別のC++関数に渡すとかできます。バッファの確保をJavaScript内で行うという方法も考えられますが、char**の扱いが必要な場面での書き方の練習です。
app.ts
var ref = require('ref'); var ffi = require('ffi'); var mylib = ffi.Library('sub', { 'fnsub_create': ['size_t', ['char**']] }); var dataPtrPtr =ref.alloc('char*'); var len = mylib.fnsub_create(dataPtrPtr); var dataPtr = ref.deref(dataPtrPtr); var buf = ref.reinterpret(dataPtr, len, 0); console.log('len =', len); console.log('dataPtrPtr=', dataPtrPtr); console.log('dataPtr =', dataPtr); console.log('buf =', buf); console.log(' (ascii)=', buf.toString('ascii')); console.log(' (value)=', buf[0], buf[1], buf[2], buf[3], buf[4]);
ちなみに、'char**'や'char*'は、'pointer'と書いても問題ないようです。
'fnsub_create': ['size_t', ['pointer']]
var dataPtrPtr =ref.alloc('pointer');
sub.h
#ifdef SUB_EXPORTS #define SUB_API __declspec(dllexport) #else #define SUB_API __declspec(dllimport) #endif extern "C"{ SUB_API size_t fnsub_create(char** dataPtrPtr); }
sub.cpp
#include "stdafx.h" #include <iostream> #include <iomanip> #include "sub.h" SUB_API size_t fnsub_create(char ** dataPtrPtr) { setlocale(LC_ALL, "japanese"); char* dataPtr =*dataPtrPtr =new char[5]; dataPtr[0] ='a'; dataPtr[1] ='b'; dataPtr[2] ='c'; dataPtr[3] ='d'; dataPtr[4] ='\0'; std::cout << "dataPtrPtr:" << std::hex << std::setfill('0') << std::setw(16) << dataPtrPtr << std::endl; std::cout << "dataPtr :" << std::hex << std::setfill('0') << std::setw(16) << (ULONGLONG)dataPtr << std::endl; return 5; }
実行結果
dataPtrPtr:0000000001F81D10 dataPtr :000000000204e9e0 len = 5 dataPtrPtr= <Buffer@0x0000000001F81D10 e0 e9 04 02 00 00 00 00> dataPtr = <Buffer@0x000000000204E9E0 61> buf = <Buffer@0x000000000204E9E0 61 62 63 64 00> (ascii)= abcd (value)= 97 98 99 100 0
1,2行目はC++内でアドレスを印字したもの。
4,5行目はJavaScript内でアドレスを確認してます。
6行目はアドレス('pointer'タイプ)をNode.jsのBufferとして解釈したもの。
var buf = ref.reinterpret(dataPtr, len, 0);
JavaScriptでBuffer確保
JavaScript内でBufferを確保して、C++に引き渡すのはずっと簡単です。
var mylib = ffi.Library('sub', { 'fnsub': ['size_t', ['char*']] }); var buf =new Buffer(5); var len = mylib.fnsub(buf);
C++側は次のような宣言です。dataPtrは普通のバッファとして使えます。
SUB_API size_t fnsub(char * dataPtr);
node-ffi wchar_t
障害
「のでーっふぃ」とかカワイイ...「ノードエフエフアイ」つまり、Node.jsがらみのForeign function interfaceです。C++ DLLとjavascriptをつなぐモジュールです。が、wchar_tがC++にうまく渡りません。困りました。
経緯
関連スペックは次のようになります。
- node.js@0.12.3
- node-ffi@1.3.1
- ref@1.0.2
- ref-wchar@1.0.0
- Visual Studio Community 2013
- Win7 64bit
テスト用のC++DLL関数は、次のように、引数がwchar_tです。
size_t fnsub(const wchar_t* txt);
また、typesriptからは、次のように接続、呼び出しをします。
var ref = require('ref'); var ffi = require('ffi'); var wchar_t = require('ref-wchar'); var mylib = ffi.Library('sub', { 'fnsub': ['int', [wchar_t]], }); var ret = mylib.fnsub('愛あればこそ。');
結果は、不正アクセスで異常終了です。困りました。
対策
ref-wcharをあきらめ、同一作者のテストコードwchar_t.jsを改変して使いました。
Nathan Rajlich@TooTallNate's wchar_t.js
改変したwchar_t.js
// original author: Nathan Rajlich@TooTallNate var ref = require('ref'); var ffi = require('ffi'); // added by eggtoothcroc var Iconv = require('iconv').Iconv; // vars used by the "wchar_t" type var wchar_size, getter, setter; // On Windows they're UTF-16 (2-bytes), but on Unix platform they're UTF-32 // (4-bytes). if ('win32' == process.platform) { wchar_size = 2; getter = new Iconv('UTF-16' + ref.endianness, 'UTF-8'); setter = new Iconv('UTF-8', 'UTF-16' + ref.endianness); } else { wchar_size = 4; getter = new Iconv('UTF-32' + ref.endianness, 'UTF-8'); setter = new Iconv('UTF-8', 'UTF-32' + ref.endianness); } // Create a "wchar_t *" type. We use the "CString" type as a base since it's pretty // close to what we actually want. We just have to define custom "get" and "set" // functions and then we can use this type in FFI functions. var wchar_t = Object.create(ref.types.CString); wchar_t.get = function get(buf, offset) { var _buf = buf.readPointer(offset); if (_buf.isNull()) { return null; } var stringBuf = _buf.reinterpretUntilZeros(wchar_size); return getter.convert(stringBuf).toString('utf8'); }; wchar_t.set = function set(buf, offset, val) { var _buf = val; // val is a Buffer? it better be \0 terminated... if ('string' == typeof val) { _buf = setter.convert(val + '\0'); } return buf.writePointer(_buf, offset); }; wchar_t.ffi_type = ffi.FFI_TYPES.pointer; // added by eggtoothcroc module.exports = wchar_t; // added by eggtoothcroc
テスト用javascript (app.ts)
var ref = require('ref'); var ffi = require('ffi'); var wchar_t = require('./wchar_t'); var mylib = ffi.Library('sub', { 'fnsub': ['int', [wchar_t]], }); var ret = mylib.fnsub('00愛0'); console.log(' len=', ret);
テスト用C++DLLヘッダ (sub.h)
#ifdef SUB_EXPORTS #define SUB_API __declspec(dllexport) #else #define SUB_API __declspec(dllimport) #endif extern "C"{ SUB_API size_t fnsub(const wchar_t* txt); }
テスト用C++DLLソース (sub.cpp)
#include "stdafx.h" #include <iostream> #include <iomanip> #include "sub.h" SUB_API size_t fnsub(const wchar_t* txt) { setlocale(LC_ALL, "japanese"); std::wcout << "txt=" << txt << std::endl; std::cout << std::hex << std::setfill('0') << std::setw(4) << (unsigned)txt[0] <<" " << std::hex << std::setfill('0') << std::setw(4) << (unsigned)txt[1] <<" " << std::hex << std::setfill('0') << std::setw(4) << (unsigned)txt[2] <<" " << std::hex << std::setfill('0') << std::setw(4) << (unsigned)txt[3] <<" " << std::hex << std::setfill('0') << std::setw(4) << (unsigned)txt[4] <<" " << std::endl; return wcslen(txt); }
実行結果
txt=00愛0 0030 0030 611b 0030 0000 len= 4
補足
文字コードについて
javascript内部(string) | UTF-16 |
FFI変換 | UTF-16 -> UTF-8 |
C++内部(wchar_t) | UTF-16LE |
javascript内部文字コードのendiannessがBig EndianかLittle Endianかは解りませんが、FFIを通すと、外部に対してUTF-8になるようです。で、wchar_tはUTF-16LEなので、変換(UTF-8 -> UTF-16LE)しなければならないようです。
改変部分抜粋
オリジナルのwchar_t.jsから必須部分を抜き出すと次のようなコードになります。
var ref = require('ref'); var ffi = require('ffi'); var Iconv = require('iconv').Iconv; var setter = new Iconv('UTF-8', 'UTF-16LE'); var wchar_t = { size: 8, indirection: 1, ffi_type : ffi.FFI_TYPES.pointer, get: function get(buf, offset) { return 'foo'; }, set: function set(buf, offset, val) { var _buf = val; if ('string' == typeof val) { _buf = setter.convert(val + '\0'); } return buf.writePointer(_buf, offset); } } module.exports = wchar_t;
重要なのは、ffi_typeの付加です。次のようにも書けます。
wchar_t.ffi_type =ffi.FFI_TYPES.pointer;
このコードはあくまでも見通しを良くする為のもので、getは機能しません。エンディアンネスも考慮していません。このコードも含め、今回のコード改変は、FFIの機構を理解しないままで、正当性は二の次にして、動くということを試したものです。悪しからず。
vs2013 express + JavaScript
症状
VisualStudio 2013 Express for WEB 上で JavaScript のデバッグしたかったのですが、ブレークポイントが利きません・・・困った。
(追記じゃ)
- NTVS Dev 2015-03-03 VS 2013.msi
なるものの存在を見つけました。普通にブレークポイントが利くそうですが、
- NTVS 1.0 VS 2013.msi (Wed Mar 25, 2015 at 7:00 AM)
よりも古いので、インストールで断られました。開発版なので1.0よりも内容的には進んでいる可能性もありますが、次の正式版まで待つことにします(他の人達は問題なく動いているらしい。もしかして私だけとか...)。
(更に追記です)
VisualStudio2013 community版を使うことにしました。しかも、TypeScriptです。InntelliSenseもブレークポイントも利きます。苦労なし。
対策
ステップ・イン(F11)を使う。
経緯
JavaScriptをPHPの変わりに使おうと目論んだのが動機でしたが見事に躓きました。昔は、emacsでPerlを書き、その後はemacsでPHPを書き。日々の作業をbashと共にこなすのが私の人生・・・なんと寂しい人生ではないか・・・そうじゃなくて・・・PCをアップデートしたのを機に、日常に変化を求め、PHPからJavaScriptに変更できないかと思ってしまったのです。
アプリを作るというのではなく、作業の自動化が目的です。.batや.shだと、DOMの扱いが面倒なのでPHPを使用しているのですが、JavaScript+Node.jsなら代替が利きそうだと思った訳です。
さて、次のような要望をemacs上で満たそうとすると、
- 補完したい。
- js2-mode, tern-mode とか?
- デバッガ使いたい。
- node.exe debug モードとか?
Node.jsも良くわからないのに環境整備とか鶏・卵です。早々に代替案を模索した結果、寄らば大樹のMicrosoftさんにお世話になろうと思いました(だめなら、emacsに戻ればいいのですから)。
インストール
VisualStudio Express 2013 for web とNode.jsをインストール。
新規プロジェクト作成 [ファイル][新しいプロジェクト...]
おぉ、JavaScript, Node.js が使えます。とりあえず、Console で。
ステップ・イン
色々、ぐだぐだして、検索しても結局わからずじまい。なんだか、「アタッチプロセス」しろというのであすが、Expressにはそんなものありません。製品版を買えと?んな高いもの?・・・インテリセンスでよしとして、デバッガはnode.exeのデバッグモードでもいいかぁ・・・と思ったのでした・・・が、たまたま、ステップ・インしたらできました。
続行
ほらほら、続行したら、ブレークポイントで止まってる。ローカル変数の表示もされてる(実行窓の後ろで見えにくいけど)。
もちろん、続けて、続行したらちゃんと最後までいきます。
うーん、なんでapp.jsが2枚あるんだ?わかりませんが、とりあえずブレークできたので、よしとします。
蛇足
この2枚のapp.jsは、ブレーク・ポイントが利くのと、利かないのが1枚ずつあるという不気味さ。閉じても大丈夫なのか?間違ったほうを閉じたら、また、ブレークポイントが・・・と思いましたが、ステップ・イン使えば問題は無いようです。
全閉じしておいて、F11(ステップ・イン)すれば、ブレーク・ポイントが有効な1枚だけが開きます。不気味だ。
(以上)
ファイルの関連付け沈黙
原因
GNUPACK emacsにファイルの関連付けをしたまま、アンインストールし、NTEmacs64をインストールしたところ、古い関連付けが不正になったため、新しい関連付けを受け付けなくなったらしいです。
GNUPack emacs | gnupack_basic-12.00-2014.12.29.exe |
NTEmacs64 | emacs-24.5-IME-patched-generic-cpu.zip |
対策
レジストリを書き換えます。
[HKEY_CLASSES_ROOT\Applications\runemacs.exe\shell\open\command] @="\"C:\\emacs-24.2-20121208\\bin\\runemacs.exe\" \"%1\""
↓
[HKEY_CLASSES_ROOT\Applications\runemacs.exe\shell\open\command] @="\"C:\\msys64\\usr\\bin\\runemacs.exe\" \"%1\""
あとは、通常通りの方法でファイルの関連付けを行います。[右クリ][プロパティ][全般][プログラム][変更]
ASRock A-Tuning FAN-Tastic でレベル(T1)が動かない
症状
ASRock A-Tuning Utility / FAN-Tastic Tuning レベル設定用のグラフで玉が動かなくなってしまった。わかり辛いので下の図で説明すると、「T1の玉」が「T0の玉」とくっついてしまって、動かなくなってしまうという症状です。
「T0の玉」は説明の為に命名したものです。本来、T0はT1と分離して(下に正常時のスクショ貼りました)、Temparature=0に張り付いていて、T1のFAN Speedに追従するはずなのですが、T1をうっかりT0とくっつけてしまうと、一体化して動かなくなってしまうのです。
対策
A-Tuningの設定ファイル(.xml)をメモ帳などで直接書き換える。
C:\Program Files (x86)\ASRock Utility\A-Tuning\Conf\Z97E4.xml
編集前
Z97E4.xmlの次の箇所「T1=0」になっているとT0とくっついて動かないので、適当に書き換えます。例えば「T1=20」などに書き換えます。
「T1=0」→「T1=20」
<GUIFanControl Enable="1" AutoApply="1"> <Item Name="FAN5" Enable="1" Interface="SIO_FAN" SmartFan="4" Control="FanReading" T1="0" T2="30" T3="46" T4="61" TCritical="80" SPD1="0" SPD2="0" SPD3="50" SPD4="100" ApplyValue="" ModelName="P67E4" LANID="STR_FANTUNING_CHASSIS_FAN2"> CHASSIS FAN2 </Item> </GUIFanControl>
編集後
「T1=20」になった状態です。
<GUIFanControl Enable="1" AutoApply="1"> <Item Name="FAN5" Enable="1" Interface="SIO_FAN" SmartFan="4" Control="FanReading" T1="20" T2="30" T3="46" T4="61" TCritical="80" SPD1="0" SPD2="0" SPD3="50" SPD4="100" ApplyValue="" ModelName="P67E4" LANID="STR_FANTUNING_CHASSIS_FAN2"> CHASSIS FAN2 </Item> </GUIFanControl>
これを保存します。あらかじめA-Tuningは閉じておかないと上書き禁止になります。上書きできない場合は、別フォルダに保存しておいてコピーするなどして下さいね。