概要
この説では、C#や.NETの知識はあるものの、C++やC++/CLIの知識はほとんど無い、という人が
ScenarioModを記述する上においてのノウハウや方法論の1つを提示しています。
ScenarioModは、C++/CLI
ScenarioModはC++/CLIで構成されています。
この意味すところは、「.NET FrameWork」のほとんど全ての資産を簡単に利用できる。
ということです。
今やWindows上の資産や便利な機能は、 .NET FrameWork、「特にC#」を中心に展開されています。
「プロユースのC/C++はわかりません、でもC#なら簡単なGUIアプリなら作れます。」
という方向へと人々の傾向が変化していくであろうことは、疑いの余地がありません。
また、マイクロソフト自身がそのように誘導していますし、
その現象は、Windowsに留まず、Mac、Linuxへと波及してゆくでしょう。
(iPhoneやAndroidのある程度の規模のゲームは、UnityのC#で作られたものが多い)
では、C#の知識を持つ人が、
ScenarioModを記述する上で、その知識を活かすにはどうすれば良いのでしょうか?
ここでは、この点にフォーカスを当ててみます。
便利なツール「C# to C++ Converter」
そこで管理人がお勧めするのが、「C# to C++ Converter」です。
このページ に 「Install C# to C++ Converter」というものがあります。
実はこれが非常に役に立ちます。
このツールは、C#のソースをC++/CLI へと非常に高い精度で変換できます。

完全なエラーのないソースであればあるほど、あるいは、
完成されたVC#のプロジェクトであるほど、正確な変換が可能となりますが、
部分的なソースでも、高い精度での変換が可能です。
下図のように左側に、C#のソースを記述します。
using System;
using System.Collections.Generic;
class Test {
void MyProc() {
List<int> mylist = new List<int>();
mylist.Add(32);
mylist.Add(25);
foreach(var i in mylist) {
Console.WriteLine(i);
}
}
}
図のように「C++/CLI」をコンボボックスリストから選択します。
using namespace System;
using namespace System::Collections::Generic;
private ref class Test
{
private:
void MyProc()
{
List<int> ^mylist = gcnew List<int>();
mylist->Add(32);
mylist->Add(25);
for each (auto i in mylist)
{
Console::WriteLine(i);
}
}
};
これがC++/CLIです。
Linqやdynaimicなど、C#4.0以降に付け加えられた機能を除けば、
C++/CLIは、C#の主要な文法にはほぼ1:1で対応しています、
又、ライブラリは同じものを参照しているわけですから、原則全て利用可能です。
C#の可変長引数なども問題なく変換出来ます。
using System;
using System.Collections.Generic;
class Test {
int MySumFunc(params int[] values) {
int Sum = 0;
foreach(int v in values) {
Sum += v;
}
return Sum;
}
void MyProc() {
MySumFunc(1,2,3,4,5,6);
}
}
同じように、ツールの左側に入力し、「C++/CLI」を選びなおしてみましょう。
(C++/CLIと見えてるなら、CTRL+Sボタンでも良い)
using namespace System;
using namespace System::Collections::Generic;
private ref class Test
{
private:
int MySumFunc(... cli::array<int> ^values)
{
int Sum = 0;
for each (int v in values)
{
Sum += v;
}
return Sum;
}
void MyProc()
{
MySumFunc(1,2,3,4,5,6);
}
};
本当にこんな記述が ScenarioModで使えるのでしょうか?
ScenarioModに貼り付けて、
「カスタム::On_プレイヤ担当ターン《メイン画面》() 」メソッド内から呼び出してみましょう。
int MySumFunc(... cli::array<int> ^values)
{
int Sum = 0;
for each (int v in values)
{
Sum += v;
}
return Sum;
}
void カスタム::On_プレイヤ担当ターン《メイン画面》() {
int sum = MySumFunc(1, 2, 3, 4, 5, 6);
デバッグ出力 << sum << endl;
}
なんということでしょう、なんという恐ろしさ。
余裕で動作します。
そうです、
これが「共通の.NETというプラットフォーム(CLR)を意識した言語同士だから持つ高い相互変換性」です。