カンテラの光の下で

dNaga392's memorandom

Chromeのタブを整理する 2020 Winter

調べてまた後で読もう/使おうと思ってどんどん増えていくものといえば?

そう、Chromeのタブです。

2020年下半期の棚卸として、開ききったタブを閉じるためブログに掃き出しておきます。

Yahoo ファイナンス

米国株の運用で一時期見ていました。Slackがこんな上がるなら夏に手放さなければよかったー(後の祭り)

Slack API

Slack の特定チャンネルの内容をスプシに書き落としたときのメモ。APIわかるまでが大変だった

Google スプレッドシート

スプシを共同編集するようになって、ユーザー入力の制御がしたくなった

Google アナリティクス

かゆいところに手が届かないので、試行錯誤していました

Twitter アナリティクス

Twitter の分析によさそう

Excel

偉大なるExcelからは逃れられない

Git

たまに忘れる設定たち

pyxel

開発していて楽しいレトロゲーライブラリ

【C++】Java の intBitsToFloat を実装する

Java の Float には intBitsToFloat というstatic関数が存在します。 これはint型のビット列をfloat型のビット列とみなして変換するものです。

int型とfloat型は、一般にデータサイズが同じ32bitです。 そのため、バイナリデータを扱うなど、ビット列を操作する場合に変換処理を使用します。

もっとも簡単なC++での実装は、次のような実装でしょう。

float intBitsToFloat(int bits)
{
    return (*(float *)(&bits));
}

しかし、これは妥当な実装ではありません。 strict aliasing rules に違反しており、コンパイラによっては警告を表示します。

適切な実装は memcpy を利用する実装です。 具体的には次の実装になります。

float intBitsToFloat(int bits)
{
    float f;
    memcpy(&f, &bits, sizeof(float));
    return f;
}

World Emoji Day 2020 🎉

f:id:dNaga392:20200717233309p:plain

リモートワークに伴いSlackやTeamsなどのチャットツールの普及によりすっかり定着したEmojiですが、Emojiを世界的に祝う日がこの7月17日だというのは知らない人も多かったでしょう。

なぜ7月17日が「World Emoji Day」なのかというと、カレンダーのEmojiの多くがこの7月17日を採用していたからだそうです📅

www.itmedia.co.jp

Emoji は日本語由来の単語ですが、Emotional にもかかっているという説もあるそうです。

ITエンジニアとしては、(マルチバイトの関係で)苦しめられることもあるEmojiですが、今日は金曜日でもあるので楽しくお祝いしてみます🍣🍺

【SQL】SQLを書く際に便利なWebツール

SQL 文を書く際に、「おおっ!これ便利!」と感じたツールを紹介します。

随時追加予定ですので、ご推薦などありましたらコメントにバシバシ送ってください!₍₍(ง˘ω˘)ว⁾⁾

  • 構文チェッカ
    • EverSQL Validator
  • フォーマッタ
    • SQLフォーマッターFor WEB
続きを読む

【C++】Windowsのバージョン情報を取得する

要点

  • C++Windowsのバージョン情報を取得します。
  • Windows 固有のライブラリ ntdll.dll の RtlGetVersion 関数を使います。
  • 内部バージョンが取得できるので、ユーザー向け表示にはひと手間必要です。

説明

Windows のバージョン情報を取得する方法はいくつかありますが、その一つが ntdll.dllRtlGetVersion 関数を使う方法です。

この方法は、マニフェストファイルなど設定ファイルが不要なため、実行の準備が少なくてすむという利点があります。

実際には次の手順で行います。

  1. ntdll.dll を利用するため、 GetModuleHandle 関数でモジュールのハンドルを取得します。
  2. RtlGetVersion を使うため、GetProcAddress 関数で ntdll.dll のモジュールハンドルから関数のアドレスを取得します。
  3. RtlGetVersion を用いて、OS のバージョン情報を取得します。

この方法で得られるバージョン情報は、RTL_OSVERSIONINFOW 構造体として取得されます。

構造体のメンバである dwMajorVersion および dwMinorVersion に、OSの内部バージョンが格納されるので、どのOSなのかは次の表に従って判断します。

dwMajorVersion dwMinorVersion
Windows 10 10 0
Windows 8.1 6 3
Windows 8 6 2
Windows 7 6 1
Windows Vista 6 0

実装例

#include <ntstatus.h>  // RtlGetVersion 関数の戻り値となる STATUS_SUCCESS の定義を使用するため
#include <windows.h>   // GetModuleHandle など、Windows特有の処理を使用するため
#include <iostream>    // std::cout など、実行結果を画面に表示するため

/// DLL 内の関数ポインタを定義
typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW lpVersionInformation);

/*!
    \brief OSのバージョンを取得。
*/
RTL_OSVERSIONINFOW GetOsVersion()
{
    auto versionInfo = RTL_OSVERSIONINFOW{sizeof(RTL_OSVERSIONINFOW), 0, 0, 0, 0, 0};

    // 1. `ntdll.dll` を利用するため、 `GetModuleHandle` 関数でモジュールのハンドルを取得します。
    auto hModule = GetModuleHandle(L"ntdll.dll");
    if (!hModule)
    {
        std::cerr << "GetModuleHandle Error" << std::endl;
        return versionInfo;
    }

    // 2. `RtlGetVersion` を使うため、`GetProcAddress` 関数で `ntdll.dll` のモジュールハンドルから関数のアドレスを取得します。
    auto RtlGetVersion = (RtlGetVersionPtr)GetProcAddress(hModule, "RtlGetVersion");
    if (!RtlGetVersion)
    {
        std::cerr << "GetProcAddress Error" << std::endl;
        return versionInfo;
    }

    // 3. `RtlGetVersion` を用いて、OS のバージョン情報を取得します。
    if (RtlGetVersion(&versionInfo) != STATUS_SUCCESS)
    {
        std::cerr << "RtlGetVersion Error" << std::endl;
        return versionInfo;
    }

    return versionInfo;
}

int main(int /*argc*/, char** /*argv*/)
{
    auto version = GetOsVersion();
    std::cout << "OSVersionInfoSize: " << version.dwOSVersionInfoSize << std::endl;
    std::cout << "MajorVersion: " << version.dwMajorVersion << std::endl;
    std::cout << "MinorVersion: " << version.dwMinorVersion << std::endl;
    std::cout << "BuildNumber: " << version.dwBuildNumber << std::endl;
    std::cout << "PlatformId: " << version.dwPlatformId << std::endl;
    std::cout << "CSDVersion: " << version.szCSDVersion << std::endl;
    return 0;
}

実行した結果がこちら。winver の結果とも合っていることが分かりますね。

f:id:dNaga392:20200513233442p:plain

参考資料

【C++】std::sort とラムダ式を使ったカスタムソート

クラスや構造体のソートには、標準ライブラリ <algorithm>std::sort を使う方法があります。 Qt でも同様の qSort がありましたが、 std::sort に置き換えることが推奨されています。

次の例は、座標情報のリストに対して、第1ソート条件にX座標の逆順、第2ソート条件にY軸の正順を適用したものです。

    QList<QPoint> points({{0, 4}, {2, 2}, {1, 3}, {3, 1}});
    std::sort(points.begin(), points.end(),
              [](const QPoint& p, const QPoint& q) -> bool {
                  if (p.x() == q.x())
                  {
                      return p.y() < q.y();
                  }
                  return p.x() > q.x();
              });
    qDebug() << points;  // => (QPoint(3,1), QPoint(2,2), QPoint(1,3), QPoint(0,4))

std::sort は昇順でソートされます。

第一引数と第二引数は、それぞれコンテナの開始と終了のイテレータです。

第三引数は bool cmp(const T &a, const T &b); と等価なラムダ式であり、operator< と同じ意味を持ちます。 つまり、上の例では p < q となるならば true、そうでなければ false となります。

Sort it Color Balls 3D

Sort it Color Balls 3D

  • 発売日: 2020/02/13
  • メディア: アプリ

コーディングのケーススタイルまとめ

コーディングにおけるケーススタイル(Case Style)とは、一つまたは複数の単語で命名する場合に、どのような表記で命名するかのスタイルです。

一般に採用されているケーススタイルは、おおむね次の3種類です。

呼称 単語の区切り
🐪 Camel case (単語の先頭が大文字) theWorldIsYourOyster
🐍 Snake case _(アンダースコア) the_world_is_your_oyster
🥙 Kebab case -(ハイフン) the-world-is-your-oyster

これらをベースにして、条件を強めたスタイルも存在します。 数学でいう「一般形」と「特殊形」の関係にあたります。1

呼称 条件
🐪 Upper camel case 先頭文字が大文字 TheWorldIsYourOyster
🐪 Lower camel case 先頭文字が小文字 theWorldIsYourOyster
🐍 Scaling snake case すべて大文字 THE_WORLD_IS_YOUR_OYSTER
🥙 Train case すべて大文字 THE-WORLD-IS-YOUR-OYSTER

ファイル名などでは、単語の区切りがなかったり、スペースを利用した命名もみられます。

呼称 単語の区切り 条件
📝 Upper case (なし) すべて大文字 THEWORLDISYOUROYSTER
📝 Lower case (なし) すべて小文字 theworldisyouroyster
📝 All Upper case (半角スペース) すべて大文字 THE WORLD IS YOUR OYSTER
📝 All Lower case (半角スペース) すべて小文字 the world is your oyster

参考資料