ところでconsolas
win10になってからconsolasフォントは綺麗ですよね。VScodeでフォントとしての格を上げました。
そんなconsolasなんですが、多のエディタやHTMLで指定すると日本語フォントがイマイチ…VScodeのように綺麗に表示してくれません。(ものによってはおまえはプロポーショナルを強引に固定してるのかってぐらい文字が左右に寄っちゃったり…)
VScodeの設定では以下のような感じで日本語設定は有りません。
Consolas, 'Courier New', monospace
一応windows.FontLinkレジストリを見てみても、リンク定義はされていません。
YuGothicでもないような綺麗さですし…。
正解はメイリオでした。
あれ?でも自分はwin7からのアプグレ組だから良いけど、win10クリーンインストールだと無いんじゃ…。
luaの内部最適化について
これメモリ確保してる?無駄に新しいの生成してない?など、luaの内部挙動についてマニュアルを見ても不明だった点を2,3書き残しておきたいと思います。
内部処理は今風でとても賢いです:Q
文字列の受け渡し
luaの引数の説明では「参照渡しされるのはテーブル」と表記されていて文字列に関しては明記されていません。てっことはもしかしてコピーされちゃうの?
というわけで、allocをフックしてメモリ確保の流れをログします。
local str = "test case !!!!!!!!!!!!!!!!" custom.alloclog(true) testcall(str) print(str) custom.alloclog(false) function testcall(str) print(str) end
custom.alloclog()はメモリ確保、解放ログ出力の自前命令、仮命令です。関数の呼び出し時にコピーされるか確認します。
一応参照渡しチェックと言うことで、元strの内容も出力しておきましょうか。
test case !!!!!!!!!!!!!!!! test case !!!!!!!!!!!!!!!!
メモリ確保ログが出ないのでコピーされていません。”低レベル層”では参照渡しがされているのがわかります。
というわけで内部で連結してみましょう。
function testcall(str) str = str.."hoge!" print(str) end
ptr:20890C0 osize:133 nsize:138 usage:244K ptr:23AB9B0 osize:4 nsize:155 usage:244K test case !!!!!!!!!!!!!!!!hoge! test case !!!!!!!!!!!!!!!!
内部連結分の確保が現れましたが大元strの内容はちゃんと維持されますので、”高レベル層”では値渡しでコピーされているかのような振る舞いです。
ちゃんと今風な言語の文字列の動き(値渡しのような振る舞いが出来る文字列)で賢い文字列でした。ありがたい!
文字列においては変更が無い限り生成が発生しないので、数字などと同じコスト(リスク無し)で渡せます。
なので、
function hogeclass:getdata() return self.data end function hogeclass:setdata(d) self.data = d end
というような、dataが100MBをこえる大きなバイナリデータのやりとりにgetter/setterを挟んでもコストが発生することはありません。安心安全。今すぐインストールです。
おまけ。
luaコンパイルにはちゃんと固定値(const)判断っぽいようなのもあるようで、
custom.alloclog(true) local str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" custom.alloclog(false)
このコードが実行されるときに"aaaaaaa...."のメモリが確保されることはありません。低レベル層では固定値"aaaaaaaaaaa...."の参照渡しで処理されます。
なので、関数の外に固定値として「const_name="hogehoge"」として宣言しなくても最適化してくれるようです。
ただし、テーブルはその限りではありませんのでご注意ください。
functionのキャッシュ
次はfunctionのコンパイル挙動について。
自分がよく使って怒られる、関数内関数みたいなものの場合のコストについてです。
function hoge(x1) function inhoge(x1,x2) return x1*x2 end return inhoge(x1+1,x1+2) end
もうちょっと低レベルに展開すると
function hoge(x1) local inhoge = function(x1,x2) return x1*x2 end return inhoge(x1+1,x1+2) end
となり、inhogeに無名関数が突っ込まれる形になります。こうしてみると、hoge()が呼ばれるごとにinhoge()のコンパイルが発生しそうですよね。
それを調べるためにinhoge()の関数ポインタを出力させます。
function hoge(x1) local inhoge = function(x1,x2) return x1*x2 end print( tofunction(inhoge) ) return inhoge(x1+1,x1+2) end
function: 023D3998 function: 023D3998 function: 023D3998 function: 023D3998
全部同値が返ってきたので、function(関数)にはちゃんと使い回せるようにキャッシュみたいなのがあるようです。賢い。
えー同じになってるだけじゃ無いの〜と言うわけで100000ループテストで、関数を外に出した場合(読込時にコンパイルされる位置)と比較してもほぼ同値でしたので問題ないでしょう…。
これで安心して関数内関数をご使用ください。
luaのメモリローダー
lua5.1も気がつけば5.3です。luaに関してはまだ若かりし5.1の頃の記事が残ってますが、良い加減ちゃんと書き直したいので1,2,3を飛ばしてloader周りから書き直したいと思います。
オンメモリ読み込み
組み込みで避けて通れないのがオンメモリ読み込みとその実装です。ファイルから読んじゃダメってやつです。デバッグは良いんですけどね。
luaの場合、スクリプト読み込みは「lua_load」を使って任意ストリーム(データを返す関数ポインタ)でロードできます。任意ポインタを関数callback時に渡せるので…
と思ったらもっと便利な「luaL_loadbuffer」があるのでこっち使えば良いですね。なんだよーもうloadでつくっちゃったよー。
- luaL_loadbuffer
http://milkpot.sakura.ne.jp/lua/lua52_manual_ja.html#luaL_loadbuffer
ちなみに、loadstringという手もあるのですが、これだとチャンク名が設定できない関係上デバッグの際に読み込みファイル名がゲットできないという致命傷がございますのでご注意くださいませ。なんせデバッグは重要ですので。
それrequireだとダメですよね
はいそうです。これだと内部requireのロードが拾えません。なので、まず読み込むファイル、そしてrequireのローダを乗っ取るの2弾構えが必要です。
本家マニュアルによりますと
package.searchers このテーブルの各エントリは 検索関数 です。 モジュールを検索するとき、 require はモジュール名 (require に指定した引数) を引数にしてこれらの各検索関数を昇順で呼びます。 検索関数は別の関数 (モジュールの ローダー) およびそのローダーに渡される追加の引数、 またはモジュールを見つけられなかった理由を説明する文字列 (または何も言うべきことがなければ nil) を返すことができます。
任侠沈没に言ってわからん。
要約すると、requireで指定した文字列を渡すので、それをチャンク(load)にして返してください。エラーならそのメッセージを返してくださいということです。
言ってるかな?…言ってるかも…。
function onmemoryloader(modulename) local filename = modulename..".lua" local data = custom.load(filename) local chank,msg = load(data,filename) if chank~=nil then return chank else return msg end end
最小構成はこんな感じかな?こんな感じかも。
「custom.load()」は仮の組み込み関数で、ファイル名を指定するとその内容の(nilを含んだ)文字列を返す命令とします。仮です。
luaに置いては基本バイナリは文字列で扱います。でもnilがあるとそこで止まっちゃうので「lua_pushlstring」でnilを許容した文字列をluaに送り込みます。という点が特殊なので作成の際は注意してください。
話が脱線すると、このあたりのバイナリデータの取り扱いの仕様もあるので、luaの標準文字コードは5.3でutf8でほぼ決定なのかなと思います。無理にutf16にしなくてもね。文字列やりとりする際は変換が必要なんですが、utf16とutf8はかなり高速に相互変換出来るのでまぁいいかなーって思います。
で、これをloaderにすり替えます。
if _VERSION=="Lua 5.1" then package.preload[1]=onmemoryloader end if _VERSION=="Lua 5.2" or _VERSION=="Lua 5.3" then package.searchers[1]=onmemoryloader end
一応バージョンによって名前が違うので、両対応しておきましょう。
とりあえず一番最初のサーチに入れないと、普通にlua標準ファイル読み込みしちゃうので、一番最初に入れます。
この場所が最良なのかどうか、と言う点は私はわかりませんので公式に聞いてください。
githubにおいておきます
https://github.com/Ko-Ta2142/lua_memoryload
まだgithub使い慣れてませんが適当に組んだものを置いておきます。zlibでお使いください。
使い方はこれをrequireすれば、それ以降のrequireで作用します。
最小限動作させるには「memoryload.onload」にロードしてバイナリ文字列を返す任意のイベント(function)をセットする必要があります。
luarocks(lua5.2 DLL) on VS2015(windows)
前に失敗したのでリベンジ。
VC(VS2013)にluasocketの.makeみながら全ソースぶっ込んで作ったことはあったのですが、monnscript使おうと思ったらモジュールの依存関係があってこれは辛いなぁ…ってことでluarocksさん。
luarocksと言われても…
lua用モジュール管理ツールです。と言われてもちょっとピンときませんよね。
luaが必要最小限の機能しか有していないので、拡張はlua言語ではなくDLLに頼ることになります。となるとコンパイルが必要。その環境依存性の高いコンパイルを吸収してくれる筈のツールになります。筈。
目的のモジュール名をお願いすると、ダウンロードしてきてコンパイルしてへいおまち!してくれる筈の夢のツールです。ありがたい!
とってもかんたんだよ(windows除く)
linuxなどでは特に問題なくluarocksがapt-getやyumなんかで出来ちゃうのですが、windowsだとそうもいきません。具体的にはコンパイルにluaのライブラリ「lua.lib」が必要なのですが、これは自力で作る必要があります。
コンパイルが成功するとluaのあるところに「share」と「lib」というフォルダを作ってluaソースと作ったDLLをそれぞれ別々に出力します。
って説明が無いので、最初迷いますよねこれ…。
まずはlua.lib
いきなりですがluaそのものをコンパイルする環境構築が必要です。自分はとりあえずVC2015で試してみます。
説明は省きますが、luaの公式ページからソースを一式ダウンロードして、空のライブラリプロジェクトに全ソースファイル突っ込んでエラーを見てちょっと抜いて、コンパイルして終わりです。詳しくは長くなるので割愛。
必要最低限な設定では以下のような感じ。
構成の種類:スタティック ライブラリ (.lib) マルチ バイト文字セットを使用する:マルチ バイト文字セットを使用する(luaはこれ重要) ターゲットの拡張子:.lib プリプロセッサ:LUA_BUILD_AS_DLL;_CRT_SECURE_NO_WARNINGS SDLチェック:いいえ すべての既定ライブラリの無視:はい (/NODEFAULTLIB)
それほど難しくありませんが、後記のエラーのためもうちょっと細かい設定が必要になりますが、今のところはパスします。
ほんとにこのライブラリ大丈夫?
これはやらなくて大丈夫です。
exeでもいいのですが、自分はDLLを使うプログラムがあったのでそれで整合性をチェックしました。新しく空のプロジェクトを作ってDLLに設定、「LUALIB_API,LUA_API」があるソースをぶち込んでコンパイル。アプリに組み込み後、相当でかいlauコードが動いたので大丈夫でしょう。
luarocksダウンロードしてインストール!と思ったら5.1入ってるんですけど…
最初のインストールに使うインストーラー的なものなので問題ありません。が、そのままインストールすると5.1になっちゃうので、別途lua5.2が必要です。上の工程でexeも作っていればそれを、無ければ公式からバイナリが取得できます。
以下のフォルダ構成フォーマットに従ってファイルをコピーして、大元「c:\lua52\bin\」をwindowsの環境変数「path」に登録します。
c:\lua52\bin\lua52.exe c:\lua52\bin\lua52.lib c:\lua52\bin\lua52.dll c:\lua52\include\*.h //ソースファイルのヘッダだけ抜き出したもの(本当はもうちょっと絞り込むんですが)
落としたluarocksのinstall.batでインストール。「linstall /?」と打ち込むと設定が出てくるので以下のようなかんじで指定の場所にインストールします。(programfilesは権限が必要になるので今回は回避しておきます)
install /LV 5.2 /LUA c:\lua52\ /P c:\LuaRocks52 /LV:luaバージョン /LUA:luaのあるところ /P:luarocksのインストール先
ベコベコベコとファイルのサーチが始まります。この時にベースのluaのバージョンが決定します。なので5.3を用意してこのインストーラでまたインストールすれば5.3のluarocksが共存できます。
途中で止まった場合はそのパスを確認してください。現段階ではファイルコピーと設定ファイルのパス訂正ぐらいしかしてませんので、パスが合っていれば概ね大丈夫です。
ではさっそくモジュールげっと
最初にゲットするものといえばluasocketというのが世の習わしです。pokemonでいうところのpikachuuuuです。
c:\luarocks52\>luarocks install luasocket
わくわく感もつかの間、エラーが出ます。clってなに?
忘れてました、VCのコンパイラを使うので「デベロッパーコマンドプロンプト」で開き直して再度チャレンジしましょう。
するとまたエラーが出るはずです。LINK1107!なにやらDLLを組み込んでコンパイルしようとしてます。そこはlibつかってくださいluarockさん。
config-5.2.luaの修正
「config-5.2.lua」がluaだけど設定ファイルになります。中身はテーブルです。ってluaそのものです。こんな感じにDLLになってる「LUALIB」のところを修正します。
... variables = { MSVCRT = 'MSVCRT', LUALIB = 'lua52.lib' } ...
これで一応コンパイルが通るとは思いますが、なにやらリンク時に「???が再読込されてる」とかなんとか言われます。
どうやらlib生成のコンパイラオプションがluarocksの時と異なるので怒られてます。なので、VCを開いてlibのプロジェクト設定を変更します。
luarocksのログを見ると
cl -nologo -MD -O2 -c ?????
となってますので、プロジェクト設定では以下に対応します。
著作権情報の非表示:はい (/nologo) ランタイムライブラリ:マルチスレッドDLL (/MD) 最適化:実行速度の最大化 (/O2)
これでもう一回rualockさんにお願いすると〜
link -dll -def:core.def -out:socket/core.dll c:/lua5.2.4/bin/lua52.lib src/luasocket.obj src/timeout.obj src/buffer.obj src/io.obj src/auxiliar.obj src/options.obj src/inet.obj src/except.obj src/select.obj src/tcp.obj src/udp.obj src/wsocket.obj ws2_32.lib Microsoft (R) Incremental Linker Version 14.00.24215.1 Copyright (C) Microsoft Corporation. All rights reserved. ライブラリ socket/core.lib とオブジェクト socket/core.exp を作成中 luasocket 3.0rc1-2 is now installed in c:\lua5.2.4\ (license: MIT)
わーい。エラー無く完了。お疲れ様です。
すっかり忘れている頃ですが、出力はluarocksではなくluaの方の「share」と「lib」にされています。
では使ってみよう…
出力されたファイル群をフォルダ構成を守ってluaを実行する所へコピペすれば準備完了です。
サンプルスクリプトを作って実行させましょう。luasocketのおまじないはこうです。
require("socket")
結果はこうです。
multiple vms detected.
深刻なエラーです。どうやらluaコアと読み込むDLLのlua内部情報が異なると出るそうです。
あぁー、先ほどlib更新したからDLLとEXEも更新しないとということで、この2つもプロジェクト設定を上記に従い再設定、再コンパイル、組み込みます。
multiple vms detected.
ぐえー。どうにもダメみたいです。
multiple vms detectedってなに?
疲れたのでluaの大元のソースをご開帳。
LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver) { const lua_Number *v = lua_version(L); if (v != lua_version(NULL)) luaL_error(L, "multiple Lua VMs detected"); else if (*v != ver) luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f", ver, *v); ...
versionチェックなんですが、version値の比較の他に、アドレスの比較もやってるようです。
今回はVM Errorって言ってるのでそのアドレスで引っかかってるみたいです。何のアドレスを比較してるの?
LUA_API const lua_Number *lua_version (lua_State *L) { static const lua_Number version = LUA_VERSION_NUM; if (L == NULL) return &version; else return G(L)->version; }
「static const」のアドレスですか…。きっとluasocket側でcheckversionをcallされてる弾かれてるんですね。luaの大元libをDLLに使ってるので一部2重コードになってますのでアドレスも違います。
つまりlua本体DLLから全命令をcallしなければなりません。なので最初の.confの設定にDLLが指定されていたのでしょう。エラーでますけど。
なーるほーどねーそういうことだったのか…。
まずDLLをコンパイルする
libだけでいけるかなーと思ったんですが、DLL生成が絶対必要になります。
厳密にはDLLじゃなくて、DLL出力した際に吐き出されるlibが必要です。とはいえ1:1対応の存在で別々に取って来てもダメなので、結局コンパイルして両方生成します。
DLLの生成方法の詳細は他のページでご覧ください!
一番簡単なのは全ソースぶち込んでエラー出たのを抜くのがてっとり早いです。(うえでは一端全部入りlibつくってからDLL吐き出してますが、必要なソースの選定に.make見ないとイケナイので面倒です)
lua52.dll 486kb lua52.lib 30kb
容量は目安です。全部入りlua.libに比べてきわめて小さいlibが出来ます。このlibはDLLに命令をそのままリダイレクトさせるためだけのlibです。
これ使えって事だったの……名前一緒だしわからないですよね……。
この2つを「c:\lua52\bin\」にぶちこんで、「ruarocks install luasocket」してやります。
ライブラリ socket/core.lib とオブジェクト socket/core.exp を作成中 luasocket 3.0rc1-2 is now installed in c:\lua5.2.4\ (license: MIT)
メッセージは上記と全く同じですが、出力されるcore.dllなどの容量が若干小さくなります。
これをluaの組み込み実行環境に持って行って
require("socket")
エラー無しで通ると思います。
終わり。疲れた…。
おまけ
ほんとは「moonscript」使いたかったんです。
試しに「luarocks install moonscript」して持って行ったら「multiple vms detected.」。え?なんで?
removeしてもinstallリストから除外されないしluarocksが壊れてるのかな?このモジュールは2つのモジュールの上に成り立っているので、それらが更新されていないとかそんな感じなのかな。一応リスト見て全部叩いては見たものの…。
結局再インストールして再コンパイルしたら上手くいきました。
V8エンジン
JavaScript組み込みエンジン「V8」にちょっとだけ手を出してみました。
なぜ?lua言語にちょっとイライラしたから…つい魔が。
Chormiumeプロジェクトのアレです。ブラウザからJavaScriptエンジン部分だけをぶち抜いたもので、みんなもプログラムに組み込んでみよう!というアレです。
windowsでもほら簡単!って事だったんですけど…気軽に言ってくれるなぁ。
ビルド方法が大きく変わりました
ふふーん。なーんだgoogleからgit.cloneしておっぱいそんいれてgypするれば終わりじゃん!って思ってたんですがダメでした。
どうやらファイルが足りないみたいです。確認したところではClangあたりでしょうか。
というわけで、googleさんからではなく、Chormiumeプロジェクトさんの方から一式セットを頂くことにします。
と、数行で済ませてますがすでに1日が経過して若干やつれてます。
- depot tools
https://www.chromium.org/developers/how-tos/install-depot-tools
(これもURL変わったりするのでだめな場合はgoogleさんに「depot tools V8 install」と聞いてみてください)
このあたりは過去と同じなので詳細は省きます。
これで揃うのは、python、git、gyp環境(ninja含む)です。
展開して、フォルダのルートで以下のバッチを実行するのですが、いくつか(DEPOT_TOOLS_WIN_TOOLCHAIN,GYP_MSVS_VERSION)windows環境変数に登録が必要なので、以下の内容なバッチファイルを作って一時的に登録させる手法を使うと楽ちんだと思います。
set DEPOT_TOOLS_WIN_TOOLCHAIN=0 set CPPFLAGS=/WX- set GYP_MSVS_VERSION=2015 set GYP_DEFINES=component=shared_library set GYP_GENERATORS=ninja,msvs-ninja rem 環境変数のパスに入れるなら不要 set PATH=%PATH%;******\depot_tools set PATH=%PATH%;******\depot_tools\python276_bin
- depot tools update/setup
depottools展開フォルダのルートでバッチ作成後実行
gclient
- ツールパス指定
windows環境変数(ユーザ)にbin,root,gypのパスを追加。
- git.clone
お好きな場所にフォルダを作ってそこでバッチ作成後実行。
VSの環境に合わせて「GYP_MSVS_VERSION」は変えてください。私は2015でやりました。
set DEPOT_TOOLS_WIN_TOOLCHAIN=0 set GYP_MSVS_VERSION=2015 fetch v8
上手くいかない場合は、コマンドプロンプトを終了させたり、パスが通っているか「~> path」で確認してみてください。
というのもね、Explolerで「シフトを押しながらフォルダを右クリックでコマンドプロンプトを開く」が便利で使うんですけど、環境変数の反映は「次回”親”アプリケーション起動時」なんです。
この時、開いたコマンドプロンプトは子プロセスなので、開き直しても反映されないのをすっかり忘れて2時間時間を無駄にしました…。調べると設定するとイベントが飛んでくる筈なんですけどね…対応していないみたいで。
やったーコンパイル…できない!
コンパイルの流れは「gypさんにお願いするとsln(VSプロジェクトファイル)が貰えるのであとはVS上でやる」というのが以前までの方法でした。
これが新しくなって「gypさんにお願いするとninjaが出てきてlibまでケジメしてくれる」ということで根本的に変わってまして、slnを吐いてくれません!おのれninjaslayer!
ともあれ、とりあえずはninjaであってもコンパイルを通さないと行けませんのでそこまではやりましょう。
今回も環境変数の登録があるので以下のようなバッチをcloneした一番上(.gitignoreがあるところ)作り、念のためVisualStudioコマンドプロンプトから実行します。(風通のでも行けた気がするような)
set DEPOT_TOOLS_WIN_TOOLCHAIN=0 set GYP_MSVS_VERSION=2015 python gypfiles/gyp_v8
なんだか幾つかのファイルでエラーが出てると思います。
よくある日本語環境下でのsjis認識によるものらしいので、この際USモードでOSを再起動させます。
「コントロールパネル−言語−地域−管理−システムローケル」で「英語(米国)」にして再起動。
(これがユーザー単位に切り替えできたら良いのですが…プログラムのUnicodeチェックするときに使ってますがいつも再起動面倒です)
これで通るはずです:Q
終わったものの、特にメッセージも無いのでどこに何が生成されたのかさっぱりですが、これで「out\」というフォルダにninjaのmakeファイルが展開されました。
なのでコンパイルしないと。
ninjaと打ち込むと「build.ninja」のあるフォルダを指定してね!って言われるので以下のようにoutのなかの「任意のフォルダ」を指定してください。
ninja -C out/release
これでとりあえずはninjaコンパイルは上手くいく行ったと思います。おつかえさま:Q
ほほーlibファイル群がよゆーで10Mこえてるぜー!でけぇ!
ちげーよ!slnが欲しいんだよ!
ですよねー。
- Cannot generate solution file of v8 with gyp for visual studio 2013
http://stackoverflow.com/questions/38015585/cannot-generate-solution-file-of-v8-with-gyp-for-visual-studio-2013
KAOMOJIまでつかって実にチャーミングです。泣いてます。かわいそう。
私なんてもう流す涙も枯れてしまったわとかそんな危険な状態です。
gypさんに以下のようにお伺いを立てればslnが出力されます。
set DEPOT_TOOLS_WIN_TOOLCHAIN=0 set GYP_MSVS_VERSION=2015 gn gen --ide=vs out/VSproject
やった!これで「out/VSproject」にslnとその部下達(プロジェクト)が吐き出されて…いました……。
現在ではいくつかDLLのコピーで引っかかります。「program files(x86)\Windows Kits\10\」に「debuggers\」が無ければ、Windows 10 SDKをもう一度インストールしましょう。
https://developer.microsoft.com/ja-jp/windows/downloads/windows-10-sdk
めっちゃいっぱいのDLLとともにソリューションが出来ましたが…こんなにいるのでしょうか?
とここまでやって貰って申し訳ないのですが、slnを開いてコンパイル……出来ません。
どうも最終的に外部コンパイラでninjaに投げるような設定みたいなので、結局sln出力の意味がありません。
マクロあたりを見てなんとか再構成とも思ったのですが、どのプロジェクトもほぼ初期状態に近い状態で、明らかにバグってるように思えます(外部コンパイラの項目も真っ白ですし…)。
luaのようにシンプルなら1からビルド用のプロジェクトが組めるのですがちょっと複雑すぎて……V8コアを突っ込んでobj作ってlinkとは行かないようですので。
結局使ってるの?
使ってません…。今のところ。力尽きました。
いつか使うかも知れません。
VS2015とVS2013共存時のC++エラー対策
書き直します。はっきり言うとどうにもインストールエラーっぽいです。
それでも以下の症状が出た場合の対処策として記しておきます。
直りました
あるときVSを起動すると特殊な処理(インストールのような)が走って設定が色々直りました。これは一体どういうことでしょうか?
- 修正パッチが来た?
- もしかして開発者登録が関係してる?
修正パッチが働いた痕跡もなさそうなので開発者登録が怪しそうです。インストール時に入力したはずなんですが、直る直前にもう一度聞かれたのでどうもにも怪しいです。
なので、現状では最新状態で且つ、開発者登録をすれば問題なく使えると思います。
症状
VS2013がある状態でVS2015をインストールします。
よくあるバージョンアップ移行組です。
以前バージョンアップに伴いパス設定をこんな感じで修正したかと思います。
http://d.hatena.ne.jp/taiyakisun/20130406/1365248215
これらの設定がどう解釈されるかというと…
Visual Studio 12.0はまえのバージョンですから違うそうじゃない。他の箇所を見ると一部は14を参照、一部は12を参照、といった感じで完全にサラダボール状態です。
こうなった場合はなんらかの原因でインストールに失敗しているようです。深く考えずに再インストールなり、以下の手段を試みましょう。
直し方
再インストールすると直るかもしれませんが、色々設定済みだとあまりしたくありませんので最後の手段としましょう。
上記の通りあるとき勝手に直りましたので、修正パッチも当てつつ、まず開発者登録の状態を勘ぐってください。現在であれば、設定の後再起動で勝手に修正されるのでは無いかと思われます。
ucrtってなに
修正されるまえはなにかにつけてucrtが無いよ!互換が無いよ!ってエラーで言われまくるので、それについて調べたことを残しておきます。
・CRT ライブラリの機能
https://msdn.microsoft.com/ja-jp/library/abx4dbyh.aspx
早速眠くなってきました。
「今度(win10)から標準ライブラリはwindowsOSの一部として管理配布します。メモリモジュールと一緒にwindowsupdaeで!」みたいなそんな感じです。
ここで重要なのは「/MT」でもこれが適用されるようなので、つまり/MTでコンパイルしてもアップデートしてランタイムじゃないけどパッチを別途ダウンロードしないと動かないので注意してください。
/MDでは解決として、同封すると良いみたいですが、ライセンスがよくわかりませ、あ、大丈夫そう。
http://dev.activebasic.com/egtra/2015/08/30/831/