2017/03/29

Raspberry Pi 2 Model BにHiFiBerry Digi+ Standardを導入してYoutube再生機にしたときのメモ

再セットアップするときには忘れていそうなのでメモ。
やりたいことは次の通り。
  • Raspberry Pi 2のHDMI端子で映像を出力する
  • HiFiBerry Digi+ Standardで音声を出力する
  • VNCでHDMIでの映像出力上で操作する
Raspberry PiにインストールしたブラウザをRDPから操作する - ももいろテクノロジーを参考にしてx11vncをインストール。
LAN内からしかアクセスできないようにするのでVNC接続のパスワードは設定しない。
x11vncのインストール。
$ sudo apt-get install x11vnc
/lib/systemd/system/x11vnc.service の作成。
[Unit]
Description=Start x11vnc at startup.
After=multi-user.target

[Service]
Type=simple
ExecStart=/usr/bin/x11vnc -auth guess -forever -loop -noxdamage -repeat -rfbport 5900 -shared

[Install]
WantedBy=multi-user.target
サービスの有効化。
$ sudo systemctl daemon-reload
$ sudo systemctl enable x11vnc.service
Configuring Linux 4.x or higher – HiFiBerryを参考にして/boot/config.txtを編集してHiFiBerry Digi+を有効にする。
$ sudo diff -u /boot/config.txt.orig /boot/config.txt
--- /boot/config.txt.orig       2017-03-29 15:49:10.000000000 +0900
+++ /boot/config.txt    2017-03-29 18:11:32.000000000 +0900
@@ -53,7 +53,9 @@
 # Additional overlays and parameters are documented /boot/overlays/README

 # Enable audio (loads snd_bcm2835)
-dtparam=audio=on
+#dtparam=audio=on
+dtoverlay=hifiberry-digi
+

 # NOOBS Auto-generated Settings:
 hdmi_force_hotplug=1
あとALSAのために/etc/asound.confを作成する。
pcm.!default  {
 type hw card 0
}
ctl.!default {
 type hw card 0
}
"$ aplay -l"でデバイスが有効になっているのか確認する。

2017/02/21

Chocolateyでローカルにインストール済みのパッケージのPackage.configを作成するWSH JScriptスクリプト

Chocolateyを使ってみようと思っていろいろ見ていたらローカルにインストール済みのPackages.configを作成するためにChocolateyGUIのインストールを紹介する記事が目に付いてなんだかなーと思ったので書いてみた。
自分で使ってないからオプションには対応していない。

2017/02/18

e-Tax平成28年分(2016年分)確定申告の「先物取引に係る雑所得等」のWSH JScriptによる自動入力

e-Taxの平成28年分(2016年分)確定申告書等作成コーナーの「先物取引に係る雑所得等」の入力を支援するWSH(JScript)スクリプトを書いた。
いままでAutoItスクリプトでやっていた(2010年, 2011年など)けどWSHでInternet Explorerを比較的容易に制御できることを去年いまさら知ったのでWSHでやってみた。

動作を確認した環境は次の通り。
  • Windows 10 Pro. x64
  • InternetExplorer 11
  • 2017/02/18時点のe-Tax平成28年分確定申告書作成コーナー
ただし「先物取引に係る雑所得等」などの入力を上記の環境で実行してデータをつくり、e-Taxでの確定申告自体はVirtualBox上のWindows 7で実行した。

入力スクリプトの作成

まずはじめにetax-futures-2016.jsをダウンロードする。
その次にダウンロードしたetax-futures-2016.jsの"/* futures"以下を申告する内容に書き換える。
// 種類 決済月 決済日 数量 決済の方法 差金等決済に係る利益又は損失の額 譲渡による収入金額 その他の収入 委託手数料 譲渡による収入金額に係る取得費 必要経費3項目名 必要経費3 必要経費4項目名 必要経費4 必要経費5項目 必要経費5
/* futures
日経平均先物ミニ 2 4 1 先物返済 10500   74  消費税 4    
日経平均先物ミニ 4 15 1 先物返済 -1000   74  消費税 4    
日経平均先物ミニ 6 10 1 先物最終決済 65911   74  消費税 4    
日経平均先物ミニ 6 10 1 先物最終決済 -66911   74  消費税 4    
日経平均先物ミニ 11 9 1 先物返済 4000   74  消費税 4    
*/

入力スクリプトの実行

Internet Explorerを操作して(保存しておいた確定申告書データから作成を再開するなどして)「【確定申告書作成コーナー】-先物取引に係る雑所得等」ページを開いておく。
所得区分を「雑所得用」などに選択する。
コマンドプロンプトから入力スクリプトを実行する。
>cscript.exe etax-futures-2016.js
エラー処理やログ出力などは実装していないので結果の確認は各自でどうぞ。

特に参考にしたページ

2016/02/20

C#の構造体の引き渡し方によるパフォーマンスの違い(修正版)

C#の構造体の引き渡し方によるパフォーマンスの違いの調査用コードにミスがあるとyosolaさんからコメントで指摘をもらっていたのでその修正版のエントリ。

修正後のコードは次の通り。
修正したのはクラス名とPoint.AddRefStructのケースでの処理時間が加算ではなく代入になっていた点(104行目の"refStructTicks += sw.ElapsedTicks;")
結果は次の通り。
size: 1000
AddStruct: 104 (1.00)
AddRefStruct: 23 (0.22)
AddInterface: 148 (1.42)
size: 10000
AddStruct: 250 (1.00)
AddRefStruct: 220 (0.88)
AddInterface: 914 (3.65)
size: 100000
AddStruct: 2332 (1.00)
AddRefStruct: 2184 (0.94)
AddInterface: 7715 (3.31)
size: 1000000
AddStruct: 21937 (1.00)
AddRefStruct: 21208 (0.97)
AddInterface: 73993 (3.37)
読み取れること:
  • 繰り返し回数が少ない場合はインターフェースを経由しない参照渡しが速い
  • ただし繰り返し回数を増やすとインターフェースを経由しない参照渡しと値渡しとの差は数パーセントまで小さくなる
  • インターフェースを経由させると経由させない場合と比較して3倍以上遅くなる
繰り返し数回実行してみたけど傾向は変わらなかった。
この結果からメソッドに構造体を渡す場合は値渡しでいいと思う。ref修飾子を書いて参照渡しにしても数パーセントしか違いがないならわざわざそんなことをする意味はない。どうせほかの部分の処理時間で関係なくなる。
またインターフェース経由で渡した場合は遅いので実行速度のパフォーマンスが気になる個所ではそれは避けるようにしたほうがいい。

最後に、前回の計測と今回の計測では環境が違う。
前回はたぶんWindows 7, Visual Studio 2010、今回はWindows 10, Visual Studio 2015。それに加えてPCも違う。
前回の計測ではインターフェース経由でない値渡しの場合とインターフェース経由の場合での差が1.0倍から1.7倍くらいだったが、今回の計測ではそれが3倍以上になっているのは、Visual Studio(Visual C#)のコード生成処理が更新されていることが原因だと思う。

2016/02/19

「公的個人認証クライアントソフト(JPKI利用者ソフト) Ver3.0」で個人番号カードの証明書確認をすると「予期せぬエラーが発生しました。(CryptAcquireContext:0x80090006)」となる場合の対処法

来年も同じことでつまづきそうなので書いておく。
Windows Updateで配信される更新を適用している環境ではこれは起こらないと思う。
自分の場合は年一回の確定申告のために常用環境にソフトをインストールするのがイヤで、手元にあったプレーンなWindows 7 SP1の仮想環境で確定申告をしようとしたところ引っかかった。

まずは現象の再現。
  1. 「公的個人認証サービス」-「JPKI利用者ソフト」を起動する。
  2. 表示されたダイアログの「証明書をみる」の「自分の証明書」をクリックする。
  3. 表示されたダイアログの「署名用電子証明書」を選択して「OK」をクリックする。
  4. ここで「エラーが発生しました。予期せぬエラーが発生しました。(CryptAcquireContext:0x80090006)」というダイアログが表示される。

もちろんこれではe-Taxで申告書等を提出できない。
試行錯誤してしまったのはスルーして、「公的個人認証クライアントソフト Ver3.0」の動作環境を確認すると更新プログラムの適用が必要とのこと。
前提となるWindows更新プログラム
 利用者クライアントソフト(Windows版)は、SHA256に対応する為、 下記のWindows更新プログラムの適用が必須です。
・Windows8.1の場合
  Windowsの更新プログラム(KB2919355)
・Windows7/VISTAの場合
  Windowsの更新プログラム(KB3035131)
  Windowsの更新プログラム(KB3033929)
Windows 8.1の場合とWindows 7/Vistaの場合とx86/x64に注意して上記のWindows更新プログラムを適用することで、「公的個人認証クライアントソフト Ver3.0」が正常に動作してe-Taxで申請書等を提出できた。

2014/03/27

「C/C++プログラミングの「迷信」と「誤解」」を読んだ

図書館で見かけたC/C++プログラミングの「迷信」と「誤解」を読んで知ったこと。
自分みたいなC++に中途半端な人にはとても有用だった。Cの細かいところとか落とし穴的なところを押さえるにもいいと思う。
C/C++迷信集 | 株式会社きじねこで読めるのかもしれない。
C++についてのみ。Cについては知識/経験なさすぎなのでスルー。
実行環境としてはVisual C++ 2013でWin32 コンソール アプリケーションで空のプロジェクトを作ってTest.cppなファイルにコードを書いてビルド&実行。

一重引用符の中には一文字しか書けない!?(p54)

コード:
// 一重引用符の中には一文字しか書けない!?(p54)
#include <iostream>
#include <ios>

int main(int argc, char* argv[]) {
    const auto ns = 'a';  // 1文字の場合はchar型
    const auto nm = 'abcd';  // 複数文字の場合はint型で値は処理系依存
    std::cout << std::hex <<
        typeid(ns).name() << ", " << ns << std::endl <<
        typeid(nm).name() << ", " << nm << std::endl <<
        std::endl;

    const auto ws = L'a';
#pragma warning(push)
#pragma warning(disable: 4066)
    const auto wm = L'abcd';  // warning C4066: ワイド文字定数の文字列は無視されます。
#pragma warning(pop)
    std::wcout << std::hex <<
        typeid(ws).name() << ", " << ws << std::endl <<
        typeid(wm).name() << ", " << wm << std::endl <<
        std::endl;

    return 0;
}
実行結果:
char, a
int, 61626364

wchar_t, a
wchar_t, a
多文字リテラル(multicharacter literal)の存在とかそれがint型になるとか全く知らなかった。
これに関してはワイド文字は素直でいい。

absは負の値を返さない!?(p123)

コード:
// absは負の値を返さない!?(p123)
#include <cmath>
#include <limits>
#include <iostream>

int main(int argc, char* argv[]) {
    const int x = std::numeric_limits<int>::min();  // -2147483648 トラップ表現
    const int y = std::abs(x);
    std::cout <<
        x << std::endl <<
        y << std::endl <<
        std::endl;

    return 0;
}
実行結果:
-2147483648
-2147483648
説明されてみれば確かにそうなんだけど全く意識したことがなかった。これ踏んでるコードってけっこうありそうな気がするんだけどこれって初見なのでどうなんだろうと不安がある。
absなんか使った記憶ほとんどないけど使いまくりなfabsはどうだろうと確認してしまった。

ポインタを型変換してもアドレスは変わらない!?(p158)

コード:
// ポインタを型変換してもアドレスは変わらない!?(p158)
#include <iostream>

class Foo {
public:
    Foo() {}
    virtual ~Foo() {}
};

class Bar {
public:
    Bar() {}
    virtual ~Bar() {}
};

class Baz: public Foo, public Bar {
public:
    Baz(): Foo(), Bar() {}
    virtual ~Baz() {}
};

int main(int argc, char* argv[]) {
    Baz baz;
    Foo *pfoo = &baz;
    Bar *pbar = &baz;
    Baz *pbaz = &baz;
    std::cout <<
        "pfoo: " << pfoo << std::endl <<
        "pbar: " << pbar << std::endl <<
        "pbaz: " << pbaz << std::endl <<
        std::endl;
    return 0;
}
実行結果:
pfoo: 001BF79C
pbar: 001BF7A0
pbaz: 001BF79C
結構初歩的なことな気がするけど知らなかった。正直恥ずかしい気とまずいコードを書いたことがあるかもしれない。
pfooとpbazの値が一致しないケースを作れない点で自分の低スキルぶりを再認識。

配列や構造体をmemsetで一括ゼロクリア!?(p174)

コード:
// 配列や構造体をmemsetで一括ゼロクリア!?(p174)
#include <iostream>

struct Foo {
    char *c;
    int n;
    double d;
    wchar_t *wcs[10];
};

void write(const Foo& foo) {
    const char* x = reinterpret_cast<const char*>(&foo);
    for (size_t n = 0; n < sizeof Foo; ++n) {
        std::cout << int(*x++);
    }
    std::cout << std::endl;
}

int main(int argc, char* argv[]) {
    //Foo foo;
    //Foo foo = {0};
    Foo foo = {};
    write(foo);

    //Foo *pfoo = new Foo;
    Foo *pfoo = new Foo();
    write(*pfoo);
    delete pfoo;

    //Foo *fs = new Foo[10];
    Foo *fs = new Foo[10]();
    write(fs[0]);
    write(fs[1]);
    write(fs[9]);
    delete[] fs;

    return 0;
}
実行結果:
00000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000
memsetとかstd::fillとかZeroMemoryを使ったりしてサーセン、理解or覚えてなかった。