メインPCが起動中やファイルアクセス中に突然電源落ちるようになった。どうもソフト的な問題ではないようだ。そこでハードを疑い、以下をやってみたが解決せず。どうも、マザーボードか電源がおかしいようだ。
続きを読む
トランプ大統領が、日本に対する貿易赤字でお怒りのようです。調べてみると、例えば2015年度は日本→アメリカ輸出額:15.1兆円に対し、アメリカ→日本輸出額:7.9兆円と、アメリカは7.2兆円の赤字を出していました。もっとも、これはiTunesや特許料等のアメリカが得意とするサービス収支が抜けているので、実際には赤字額はもっと小さいはずですが、それはさておき。
トランプ大統領は、日本にもっとアメリカ製品を買え!と主張していますが、この主張は正当なのでしょうか?たしかに、アメリカには日本製品が多数ありました(過去形)が、日本にも米国製品が多数あるような気がします。そこで、相手国の製品を国民一人あたりいくら買っているか単純計算してみました。
結論から言うと・・・日本人は、アメリカ人よりも相手国の製品を買っているようです。国力の差を勘案すると、現状でも妥当ではないでしょうか。
以下、詳細です。使用するデータはすべて2015年度のものにしました。
まず、貿易額ですが、これは前述の通り。データは「米国経済と日米経済関係(平成29年3月)(PDF)」(外務省)の最終ページから持ってきました。
次に、人口です。データは国連のWorld Population 2015から持ってきました。
さて、これらのデータを元に、各国民が相手国から一人あたりいくら輸入しているか計算します。結果は以下の通り。
このように、単純計算だと日本人のほうがアメリカ人より相手国から沢山買っているという結果になりました。
なおこの計算は、互いに原材料の貿易が無いことを前提にしていますが、実際には部品のやり取りがあるためこの通りにはなりません。また、互いに同じくらい魅力的な製品を、同種類ずつ製造できることも前提としています。実際には人口が少ないほど製品ラインアップが減り、同種類というのは困難になります。とはいえ、人口が1億人以上もあると、これによる差は小さそうです。
以上を勘案すると、日本人もアメリカ人も、互いの国力に応じた額の取引をしているのではないでしょうか。
フォルダ選択ダイアログを表示するため以前はSHBrowseForFolderを使っていたんだけど、MSDNによるとVista以降はIFileDialogを使うことが推奨されるらしい。
そこで、IFileDialogを使うよう、以下の通り実装した。
(2018/06/23追記:IFileDialogはWindowsVista以降でしか使えない。そのため、stdafx.hのWINVER等を0x600以上にする必要がある。後述。また、マルチバイト文字セットでは操作できない。Unicode必要。)
gistbfbc99d6b26024ca291f41e586f96900
なお、pDialog->Show(NULL)としているが、NULLのかわりに呼び出し元のhWndを指定してもよいようだ(MSDNより)。また、IFileDialogのインスタンスを示すCLSIDは存在しない?ようで、CoCreateInstanceではCLSID_FileOpenDialogを引数に指定している。
取得したインスタンスや、呼び出し先関数が確保したメモリは忘れずに開放すること。
2018/06/23追記:
下記エラーが出る場合は、stdafx.hに記述した動作OS情報が間違っている可能性があります。
・__uuidofのオペランドには__declspec(uuid('...'))が指定されているクラス型または列挙型を使用する必要があります
・error C2787: 'IFileDialog': このオブジェクトに関連付けられた GUID はありません。
解決方法は下記。解決方法調べたら、自分のページが引っかかった・・・過去にも同じことで困ったのか、自分・・・。
IFileDialogやIFileOpenDialogを使おうとしたら、「error C2787 このオブジェクトに関連付けられた GUID はありません。」というコンパイルエラーが出た。
原因は、元のソフトがWindowsXp以降で動作するようにしていたため。上記インターフェースは、WindowsVista以降でしか使えないのだ。
どのバージョン以降を動作対象にするか指定しているのは、stdafx.hの以下の箇所。
0x0501はWindowsXp以降を動作対象とする設定なので、これをVista以降となる0x0600に書き換えてやる。
これでコンパイルが通るようになった。
WINVER等とWindowsのバージョンの関係は、下記に公式情報がある。
Using the Windows Headers (Windows)
英語だが、各表右上の"Value for なんとか"という部分に、どの定数に関する表か書いてある。
なんとなくドスパラに寄って商品眺めていたら、GTX1060か1070あたりを買いたくなった。でも、グラフィックボードの場合大きさの問題が有る。いずれも、ボードが長かったり厚かったり(2枚分からはみ出る)しているので、そもそも自宅PCに挿せるのか調べてから買うことにした。
ところで、そもそもグラフィックボードを買い換える必要があったのだろうか?そこで、今使っているGTX770と、性能比較を仕様書ベースでしてみた。
型番 | GTX770 | GTX1060 | GTX1070 |
---|---|---|---|
アーキテクチャ | Kepler | Pascal | Pascal |
コードネーム | GK104 | GP106 | GP104 |
CUDAコア数 | 1536 | 1280 | 1920 |
コアクロック(MHz) | 1046 | 1506 | 1506 |
メモリI/F(bit) | 256 | 192 | 256 |
メモリ帯域(GB/s) | 224.32 | 192 | 256 |
自分はメモリ帯域気にする派なので、GTX1060は無いな・・・。となると、GTX1070との比較だけど。コアクロック1.5倍は魅力的。でも、問題は価格。4~5万円台か・・。ちょっと保留だな。
MFCで画像をお手軽に使えるクラスCImageから、画像処理の定番OpenCV用のクラスcv::Matへ画像をコピーするのは、一見簡単だが罠がある。CImageが保持している画像データへのポインタはCImage::GetBits()で取得できるのだが、このポインタ、データの先頭を指す場合と、最後の行の先頭を指す場合があるのだ。そのため、GetBits()で取得したポインタと画像サイズを元にmemcpyするとアクセス違反が発生しうる。
また、CImageはメモリアクセスを効率化するためか、行末にビットスタッフを行う。例えば、1行あたりのデータ量が405バイトの場合、実際には408バイトが使われる。一方、cv::Matはcreate()で作成したオブジェクトならば常に全データが連続する(ビットスタッフなし)(cv::Mat::isContinuous()のドキュメントに記載)。そのため、そもそもコピーするデータが異なっている。
以上を踏まえると、以下のようなコードが必要となる。