C++/CLIで国際化文字列リソースを追加

メインのフォームFormMainがあると仮定

プロジェクトにリソース(*.resx)を追加、ここではStringResource.resxとStringResource.ja-JP.resxを追加する。

FormMainに以下のコードを追加

実装

sInに渡された文字列がリソースにあればそれを返す。なければそのまま返す。
CultureInfoをGetStringの第二引数に渡せるがここではスルー

VC2008でCRTのないEXEを作成する

普通にwin32プロジェクトを作成
clipshot 2015-12-18 00-00-44
/NODEFAULTLIBオプションを有効に、これでCRTはリンクされない。
clipshot 2015-12-18 00-03-05
ビルドするといろいろリンクエラー、これはCRTの機能を呼んでいるから出る。

Basic Runtime Checkをデフォルトに
clipshot 2015-12-18 00-07-06
ビルド

Buffer Security CheckをNoに
clipshot 2015-12-18 00-08-53
ビルド

以下を定義

これでビルドできて動いた。しかしmemsetを使っていると問題がある。

このようなコードでもコンパイラはmemsetを呼ぶようで、これが見つからないと怒られる。自分で定義する。

これでビルドできたがVC6だと今度はintrinsicの関数を定義するなと怒られる。その場合は以下のプラグマで回避する

MingWとEclipse CDTでWin32プログラムでJNIのランチャー作成

XP sp3で挑戦
まずMingWをインストールする。
01mingdown

デフォルトのフォルダへ
02minginst
msysは今回は使わないと思うけどとりあえずインストールgcc-g++は必須のはず。
3minginst2

次にjavaをインストール。
clipshot 2015-12-15 07-16-41
警告はスルー。8.66をインストールした。PATH関係でエラーが出るかもしれないのでいったんログオフ。

次にeclipse CDTのインストール、eclipse.orgへ行ってCDTをダウンロード、ここではeclipse-cpp-mars-1-win32.zipをダウンロードしてC:\に解凍。

起動しようとするとすぐ終了してしまうので、コマンドラインからeclipsec.exeで起動してみる。
clipshot 2015-12-15 07-24-39
メモリーが足りない?eclipse.iniの最後を以下のように書き換えて起動。

起動できた。
clipshot 2015-12-15 07-27-51
とりあえずHello World C++というのを作ってみる
clipshot 2015-12-15 07-32-37
メニューから{Project][Build All]

ビルドできた。次に[Run][Run Configuration]で以下のように設定。というか自動で作られる。
clipshot 2015-12-15 07-36-21
[Run][Run]を実行。しかし!!!Hello World!!!が表示されないので、コマンドラインから起動してみると以下のエラーがでた。
clipshot 2015-12-15 07-39-41

リンカオプションに-static-libgcc -static-libstdc++をつけて解決
clipshot 2015-12-15 20-35-04
clipshot 2015-12-15 20-36-28
コンソールを出さないWindowsプログラムを作るため、Makefileプロジェクトを作った。
clipshot 2015-12-16 03-06-44

ソースファイル

メイクファイル

フラグの指定の仕方が強引だがLDFLAGSが効かないみたいなので今はこれで。

実行
clipshot 2015-12-16 03-22-35

これでwin32アプリの準備はできたので、JNIを利用してjavaのランチャーを作る。jni.hがJDKに入ってるので仕方なくJDK7をインストール。
mymain()を作成。http://homepage2.nifty.com/igat/igapyon/diary/2006/ig061108.html からコピペ

メイクファイル修正

ビルドするとエラー

jvm.libがこの関数をエクスポートしてないみたいなので、dllから直接よぶ。今回はjvm.dllの位置は固定でやる。

これでVMは作れたのでパラメータを調節すれば動くだろう。
CDTはいろいろくせがあって慣れないと使いづらい。

Eclipse MarsがXPで起動しない

eclipseの起動はeclipse.exeで行うがコマンドラインのeclipsec.exeもあるので、コマンドラインからこれで起動するとエラー内容が表示される。

clipshot 2015-12-16 02-48-38

eclipse.iniに起動時のパラメータが書いてあるのでこれのメモリ部分を以下のように修正

-XmsはJavaのメモリの初期値、-Xmsは最大値

これで起動はしたがメモリが足りなくなるのかもしれない。

*あるいは-Xmsは削除してもいいかもしれない。

C#で複数形を単数形に変換する

.NET4のFULLが必要(Client Profileの場合プロジェクトの設定を変える)
System.Data.Entity.Designを参照に追加

C++ 右辺値参照とmove

右辺値参照は「あとは死ぬだけになったオブジェクトの参照」

右辺値参照がわかりづらいのでメモ&テスト

まず、生のデータNamaを定義しよう。

次にこれを扱うクラスNamaHandlerを定義しよう。

問題ない。コンストラクタでNAMAを初期化し、デストラクタで解放。なお例外はスルー。
しかしこのクラスには問題がある。コピーコンストラクタを定義してないので、コピーするとポインタがコピーされ、デストラクタで2重deleteになってしまう。よってコピーコンストラクタを定義しよう。

アサインメントのオペレーターも定義しよう。

コピーコンストラクタはインスタンスを作成するときに呼ばれる(=を使っても)。operator=は=したとき呼ばれる。
実行しよう

ここでNamaHanderを返す関数getNama()を定義しよう。

全部まとめたソース

このコードには論理的に問題はないが、やたらとコピーが呼ばれる。上の42行目と44行目でやたらと呼ばれる、しかも作ったオブジェクトをすぐ捨てていてもったいない。そこで右辺値参照を定義してみる。

&を&&に置き換えただけだが、実行してみるとここに来ることがわかる。どういう条件でくるのか?
参照があとは死ぬだけであとはデストラクタが動くだけのオブジェクトの参照のときに呼ばれる。
これを生かして実装を変えてみよう。

&&で受け取ったオブジェクトのコピーをせずにポインタだけコピーしている。nameの方はNULLをセットしてデストラクタが呼ばれても大丈夫なようにしている。

と思ったが上のコードにはひとつ問題が。ある?
thisと&&が同じ場合のときを考えていなかったがそんなことはあるだろうか?ここではないとしてスルー

std::move()

上記の例は全部コンパイラが勝手に呼んでくれたものだった。
コンパイラは死ぬだけになったオブジェクトを判別できれば呼んでくれるが、すべてのものを判別できるとは限らない。

4行目のn1はもう使ってないので&&を呼んでくれてもいいのに呼んでくれない。そこで書き換えよう。

ここまで全部のソース

std::moveはよっぽど特殊じゃないと使わない気がするし間違うとやばい。