忍者ブログ

Memeplexes

プログラミング、3DCGとその他いろいろについて

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。


DirectX10 + C++/CLI ウィンドウの表示

最近忙しかったので久々の投稿です。
こう時間が空くとどうも精神的にやりにくくなりますね・・・。

さて、前々から思っていたのですが、そろそろDirectX10をやってみたいと思います。
言語はC#・・・を使いたいところですが、ManagedDirectXは消滅してしまったので、泣く泣くC++/CLIを使います。
OSはVistaオンリーです。DirectX10はXPでは使えません。

まずはSDKのダウンロードです。
現在最新のDirectX のSDKは(November 2007)です。
Novemberって何月だっけ・・・と思って辞書で引くとなんと11月、つまり今月です!
良いタイミングでDirectX10をはじめたことになります。
幸先良いスタートです。

また、Windows Platform SDKをインストールする必要もあるようです。(もちろんWindows Vista用のです)
なんせVisual C++ ExpressにはWindows.hが付いてきません
DirectX10のサンプルを動かすにはWindows SDKのIncludeファイルとLibファイルが必要です。

で、Windows SDKのIncludeファイルととLibファイルをC++/CLIのコンパイラから使えるようにします。(単にコピー&ペーストでいいでしょう。(いいわけない。環境変数LIBとINCLUDEでそれぞれのディレクトリのパスをセットしてやりましょう。)いちおうWindows SDKには"Integrate Windows SDK with Visual Studio 2005"というのが付いていますが、cl.exeには効果が無いように見えます。)

これで準備は整いました(たぶん)。
さっそくやってみましょう!



C++はほんと久しぶりですし、C++/CLIにいたっては初めてなので、少しずつ進んでいくことにします。

まずはウィンドウを作ってみます。


Dx10Test.cpp
#using<System.Windows.Forms.dll>
#using<System.dll>

using namespace System::Windows::Forms;

int main()
{
	Form ^form = gcnew Form();
	form->Show();
	
	while(form->Created)
	{
		Application::DoEvents();
	}
}

で、Visual Studio 2005 Command Promptからコンパイルです。

cl /clr dx10Test.cpp

CreatedWindow.jpg
よし!
上手くいきました。
DirectXを使う場合はApplication::Run()を使えないのがちょっと残念ですが、まあいいでしょう。
Win32APIを使うよりははるかにましというものです。


さて、うまくウィンドウを表示できたので、こんどはちょっと遊び心を加えて見ましょう。
実行結果はそのままに、XNAっぽくリファクタリング?です。
#using<System.Windows.Forms.dll>
#using<System.dll>

using namespace System::Windows::Forms;

ref class Game : Form
{
	public:
	void Run()
	{
		Show();

		while(Created)
		{
			Application::DoEvents();
		}
	}
};

int main()
{
	Game ^game = gcnew Game();
	game->Run();
}




 

拍手[0回]

PR

[C++/CLI] .netオブジェクトを作る(gcnew)

gcnew

C++/CLIでは、.netオブジェクトを作るのに、(newではなく)gcnewを使うそうです。
(gcnewはマネージトな型のインスタンスを作るやつで、これによって作られたものは参照型だろうと値型だろうとガベージコレクションのヒープに確保されます。)

そしてそのgcnewによって返されるのも、ポインタではなくハンドルというものになるそうです。(*ではなく^を使うことになります。)

なお、ハンドルを使うからといってポインタがなくなってしまったわけではなく、C++/CLIではネイティブのクラスをnewしたりとかはできます。(でなきゃなんでC++なんて使うのかわかりませんしね)

HelloWorld.cpp
#using<System.Windows.Forms.dll>
#using<System.dll>

using namespace System::Windows::Forms;

int main()
{
	Form ^form = gcnew Form();
	Application::Run(form);
}

このプログラムはWindowsFormsでウィンドウを表示します。
ここでは.netオブジェクトのformを作っているため、gcnewを使ってインスタンスを生成しています。(newだとコンパイルエラーになります)

※ちなみに、ここでSystem.Windows.Forms.dllだけでなくSystem.dllまで#usingしているのは、System.ComponentModel.Componentを使っているからです。(これがないとコンパイルエラーになります。)


メンバへのアクセス

gcnewとnewはいろいろ違うところがありますが、メンバへのアクセスは同じで、->を使います。
#using<System.Windows.Forms.dll>
#using<System.dll>

using namespace System::Windows::Forms;

int main()
{
	Form ^form = gcnew Form();
	form->Text = "Hello World!";
	Application::Run(form);
}


nullptr

ハンドルの変数は、ポインタと違ってNULL(0)にすることができません。
かわりになるのがnullptrです。

Form ^form = nullptr;

ちょっとややこしいですが、nullptrは、ハンドルだけではなくポインタの変数にも代入することが出来ます。

int *p = nullptr;

拍手[6回]


[C++/CLI] .Netアセンブリをインポート

C++/CLIでの.netアセンブリのインポートに手間取ったのでメモしておきます。

アセンブリのインポートというのは、たとえばWindowsFormsを使いたい時に参照としてSystem.Windows.Forms.dllを追加するアレです。
C#のコンパイラcsc.exeでいう/refereceオプションでやるやつです。これをしないとコンパイルできません。
しかしC++/CLIのコンパイラ、cl.exeにはそのようなオプションがぱっと見、みあたりません。(後でわかったのですが、/FUがそれっぽいです)

どうやらC++/CLIでは#usingでソースコード中に指定できるようです。

HelloWorld.cpp
#using<System.Windows.Forms.dll>

int main()
{
	System::Windows::Forms::MessageBox::Show("Hello World");
	return 0;
}

コマンドラインは特に変わったところはありません。

cl /clr HelloWorld.cpp

b22bb76d.JPG

よし!できました!
コンパイラのオプションではなくコード中で指定できるとは意外でした。


もちろん/FUオプションを使ってもOKです。(#usingを使ったかのようにコンパイルすることを強制(force)するという意味のようです。)
HelloWorld.cpp
int main()
{
	System::Windows::Forms::MessageBox::Show("Hello World");
	return 0;
}


Visual Studio 2005 Command Prompt
cl /clr /FUSystem.Windows.Forms.dll HelloWorld.cpp






拍手[0回]


[C++/CLI]でSystem::Console::WriteLine

DirectX10をそのうちやる予定なのでC++のリハビリをしなくちゃいけません。

というわけでC++/CLIの練習です。(本当はやりたくないんですが・・・)

HelloWorld

簡単なものから行くつもりなのでVisual Studioはオーバーキルでしょうから、コマンドラインからコンパイルすることにします。

C++/CLIのコマンドラインのコンパイラはcl.exeで、Visual StudioのツールのVisual Studio 2005 Command Promptから使えます。(これはVisual C++ Expressについてくるみたいです。"~から使えます"といいましたが、むしろこれがないと困ります。普通のコマンドラインからだとclのパスを通してもコンパイルが上手くいきません。)

まずはさっそくHello Worldです。
HelloWorld.cpp
#include<iostream>

int main()
{
	std::cout << "Hello World!" << std::endl;
	return 0;
}

なんの変哲もないHello Worldです。
これをコンパイルするには、Visual Studio 2005 Command Promptからこうやります:
cl HelloWorld.cpp

これで異常な量の警告と共に(笑)、いちおうコンパイルが成功します。

.Net

次はC++/CLIから.Net Frameworkのライブラリを使ってみす。
これが使えてこそのC++/CLIですからね!

HelloWorld.cpp
int main()
{
	System::Console::WriteLine("C++/CLI!");
	return 0;
}

コマンドラインはさっきとちょっと違って/clrオプションが必要になるようです。(でないとエラーが出てコンパイルできません。コンパイラが'System'はクラスでもネームスペースでもないとか文句を言い出します)

cl /clr HelloWorld.cpp

/clrオプションを指定するとCommon Language Runtime用にコンパイルするそうです。
で、こうやってコンパイルするとXMLのマニフェストファイルと共に、HelloWorld.exeが作られます。

ここでは.net のライブラリだけを使いましたが、混ぜることも出来るようです。

HelloWorld.cpp
#include<iostream>

int main()
{
	std::cout << "Hello World" << std::endl;
	System::Console::WriteLine("C++/CLI!");
	return 0;
}

cl /clr HelloWorld.cpp

拍手[0回]


C++/CLIのコンパイラをコマンドラインから使う

以前、
C++/CLIのコンパイラ、cl.exeをコマンドラインから使うとエラーがでる!
直すにはパスを設定しなくちゃ!

みたいなことを書いたような気がしますが、実はそんなことをしなくても良かったみたいです。

このページ
http://dev.tyzoh.jp/trac/secure-sbm/wiki/VC-Install
の最後の方にきちんとした説明がありますね。

「スタート」→「Visual C++ 2005」→「Visual Stdio Tools」→「Visual Studio 2005 コマンド プロンプト」
できちんとcl.exeが使えるようです。(かんたんなHelloWorldで試してみたらうまくコンパイルできました)

ぼくが今まで苦労していたのは何だったんでしょうね……。

拍手[0回]