イネマルのプログラミング備忘録

趣味プログラマーのメモ。ニッチなネタから暗黙知まで無保証で公開。

C / C++ の共用体(union)を初歩的に使う

入門時にイマイチ使いどころがわからんかった共用体

プログラミングを初めて超初期のころ入門書で出会った
”union” ”共用体” のキーワード
自分の使っていた入門書では
構造体の直後位に解説されていて
いったいどこで使うの?
といった感じで放置していたが
最近使う機会があったので、一応覚書

(自分なりの)結論

キャストとかを駆使せずに”データにアクセスする手段”
記述法だけ似ている構造体とは別物と考えて良し

目的

構造体にオペレーターやキャストを使用せずに配列のようにアクセスする

確認用のプログラム

Vector3型風の構造体pos{ x y z } の各要素に”[ ]”でアクセスする。
本来ならposは配列でないので”[ ]”でアクセスできないが
共用体の機能でアクセスを可能にする
※動作確認は、VC2013

#include	<iostream>
#include	<array>

int main()
{
	using namespace std;

	union testUnion{
		struct { float x, y, z; } pos;
		array<float, 3> v;	// 純粋なCなら float v[3];
	};
	testUnion uni;

	uni.v[0] = 100.0f;		// uni.pos.x = 100.0; と同じ
	uni.v[1] = 200.1f;		// uni.pos.y = 200.1; と同じ
	uni.v[2] = 300.2f;		// uni.pos.z = 300.2; と同じ

	// つまりこう書ける
	for (int id = 0; id < 3; ++id){
		uni.v[id] += 0.5f;
	}

	// 値表示
	cout << uni.pos.x << endl;
	cout << uni.pos.y << endl;
	cout << uni.pos.z << endl;

	// 入力待ち
	rewind(stdin), getchar();
	return 0;
}

あとがき

記事にするほどのネタでもないけど入門時の自分が見たら
少しくらいは助かる気がしたので備忘録行き

C# + DXライブラリ でIMEが動作しなくなる現象の回避方法

f:id:inemaru:20151125141302p:plain

C#+DXライブラリで IMEが無効化されてしまう現象

C#のWindowsFormApplicationとDXライブラリのC#用dllを使い
フォーム上でテキスト入力ができるコントロールを使うと
”ImeModeをOnにしてもIMEが無効化されてしまう”
現象にハマり・・・
とりあえず解決方法だけわかったので備忘録行き。

結論

”MakeKeyInput関数を呼ぶ!”

確認用のプログラム

注意点としては、DxLib_Init関数よりも後にMakeKeyInput関数を呼ばないと効果がないという点です。

※動作確認は、VS2013で行いました

namespace CSFormApp
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            this.StartPosition = FormStartPosition.Manual;
            this.Location = new Point();
            this.StartPosition = FormStartPosition.CenterScreen;
            DX.SetOutApplicationLogValidFlag(0);
            DX.SetUserWindow(this.Handle);
            DX.DxLib_Init();
            // IMEを有効にする為の裏技
            DX.MakeKeyInput(0, 0, 0, 0);
        }
    }
}

あとがき

DXライブラリ内で呼ばれるAPIの関係で
こういった現象が起こっていると思われます。(たぶん)

とにかく
DX.DxLib_Init();より後にMakeKeyInput関数をを呼べばIMEが有効になるので、

とりあえず使えるようにするのであれば、
DX.MakeKeyInput(0, 0, 0, 0);
コンストラクタやフォームロード時に呼べば解決します。

C++でワイド文字(wchar_t)を使うときの注意点 ~ロケールを添えて~

f:id:inemaru:20150923003606p:plain

wchar_tを使う!

c++で文字を扱うときに、char型とwchar_t型があります。
char型と同じ感覚で使うと、要らないところでハマります。
自分がハマったので備忘録行き。

先に、結論だけ書くと
”wchar_tを使うならロケール設定をしよう!”
という事です。

確認用のプログラム

C++で現在のロケールを取得しながら
処理を目で追ってみました。

ロケールを取得した段階で "C" が返ってきたら危険。
即座に、設定するべきでしょう。

※動作確認は、VC2010とVC2013で行いました

#include <iostream>	// 標準入出力
#include <locale>	// ロケール関連
#include <clocale>	// Cのロケール関連
#include <string>	// stdの文字列クラス

using namespace std;

int main(){
	// 適当な文字列変数
	string	str("char");
	wstring	wstr(L"wchar_t");

	// ロケールを表示する関数
	auto DispLocale = [](){
		string locstr = std::locale().c_str();
		if(locstr == "C"){
			locstr += "(初期値です)";
		}
		cout << "現在のロケールは、" << locstr << endl << endl;
	};

	// 現在のロケール設定を表示
	DispLocale();

	// char文字の出力
	cout << str  << " char(string)は特に設定なしで表示できる" << endl << endl;

	// wchar_t文字の出力
	cout << "ロケールの設定なしでwcoutすると強制的にwcoutの処理が打ち切られる?" << endl << endl;
	// wcout << wstr2 + L"日本語は表示されない" << endl;
	
	// ロケールの設定
	cout << "ロケールの設定を変更します" << endl << endl;
	locale::global(locale(""));	// ""でシステムのデフォルトになるそうです
	// もしくは、
	//locale::global(locale("japanese"));
	// かつ、WindowsAPIを使うなら
	//setlocale(LC_ALL,"japanese");

	// 変更されたロケール設定を表示
	DispLocale();

	// wchar_t(wstring)は設定すると表示できる
	wcout << wstr + L" 日本語が表示される!" << endl << endl;
	
	rewind(stdin), getchar();	// キー入力で終了

	return 0;
}

あとがき

以下のリンクがすごく参考になりました。
http://tkmakwins15.tuzikaze.com/contents/winapicpp4.htm

単純にwchar_tで日本語が使いたいのであれば
std::locale::global(std::locale(""));
の一行で一応動いているようです。

ただし、WindowsAPIを使用するなら
std::locale::global(std::locale("japanese"));
std::setlocale(LC_ALL,"japanese");
とするべきでしょう。


Visual Studio 2010 C++ リファクタリング

f:id:inemaru:20150912215136p:plain
【目的】
今更だけど Visual Studio 2010 C++リファクタリング(自動リネーム)を使う

【達成条件】
・無料でやる

【注意】
・正攻法ではありません(故に↓)
・すべて個人の責任で行ってください(こちらは一切の責任を持ちません)
・VS2013(以降)は、公式で配布があるので無用の産物。

【環境】
・動作環境
  Windows 8.1 Pro
・開発環境
  Microsoft Visual Studio 2010 Professional

【方法】
1: Refactor!C++をダウンロード
2: RefactorCPP-11.2.7.exeをインストール
3: インストール完了後にシャットダウン(※この時、絶対にVSを起動しないこと)
4: CodeRushXpressをダウンロード
5: インストール完了後にシャットダウン(※この時、絶対にVSを起動しないこと)
6: PCを起動したらVSを起動し、エラーが出なければ成功!


【ちなみに】
・途中の工程で、もしVSを起動すると・・・
初回起動のみ正常に動作(してるように見える)、
2回目以降の起動で、ものすごい勢いでメモリを消費して
下手するとPCごと落ちます。

・ちなみに失敗したときのエラーはこんなの
devenv.exe Assert Failure
Expression: [mscorlib recursive resource lookup bug]
Description: Infinite recursion during resource lookup within mscorlib. This may be a bug in mscorlib, or potentially in certain extensiblity
points such as assembly resolve events or CultureInfo names. Resource name: Word_At

エラーの正体・・・拡張機能で使用されている実行ファイルのバグ

【あとがき】
約1年前に、身内で話題になり、結構頑張って調べた後
一過性の話題のまま忘れ去られようとされていた情報
データの整理中に当時自分が作った、インストールのメモが出てきたので備忘録行き決定
それが、今更VS2010のネタを書くに至った理由

ブログはじめました。

はじめまして、こんにちは。

 

技術的なことを中心に、

備忘録的な感じで更新して行きたいと思ってます。

 

がんばるぞ!