強引な機能は、たまにではあるが確実にありがたい
D言語は、C言語の関数を呼び出せるように設計されています。
C言語の呼び出し規約に従った関数を作れるため、今までにC言語を使って作られたライブラリを、そのまま利用出来ます。
ただし、C言語は構造体のポインタを引数として渡すことが多いため、構造体のポインタから要素を読み出す機能を、専用の演算子によって定義しています。
D言語はポインタを扱えますが、ポインタを明示的に引数として渡すようなプログラムは推奨していません。そのため、構造体のポインタから要素を読み出す機能は使えません。
C言語で書いてみると
#include <stdio.h>
typedef struct{
unsigned char red;
unsigned char green;
unsigned char blue;
} Color;
void tset(Color* color){
printf("Color is #%02X%02X%02X.", color->red, color->green, color->blue);
}
// この関数は引数、戻り値、中身を変更しないものとする
void call_func(void (*func)(Color*), Color* color){
func(color);
}
int main(char** agev){
Color color = {34, 34, 160};
call_func(tset, &color);
return(0);
}
これをD言語で書き直してみると
import std.stdio;
struct Color{
ubyte red;
ubyte green;
ubyte blue;
}
void tset(Color* color){
// ()で囲まないと「color.redのポインタ」と解釈され、エラーが出る
writefln("Color is #%02X%02X%02X.", (*color).red, (*color).green, (*color).blue);
}
void call_func(void function(Color*) func, Color* color){
func(color);
}
int main(char[][] agev){
Color color = {34, 34, 160};
call_func(&tset, &color);
return(0);
}
キャストを使った書き方は、
import std.stdio;
struct Color{
ubyte red;
ubyte green;
ubyte blue;
}
void tset(ref Color color){
writefln("Color is #%02X%02X%02X.", color.red, color.green, color.blue);
}
void call_func(void function(Color*) func, Color* color){
func(color);
}
int main(char[][] agev){
Color color = {34, 34, 160};
writefln("Hello, DMD world!");
call_func(cast(void function(Color*))&tset, &color);
return(0);
}
キャストを使ったコードと使わないコード、どちらが綺麗に見えますか?
私には使ったコードの方が綺麗に見えますが、そうでない人もいるかもしれませんし、実は私から見てもより綺麗な書き方を行えるのかもしれません。
そして一番の問題は、的確に問題を提示しているサンプルコードを書くだけの技量が、私に備わっていないということです。経験が浅い故に。
2009/10/10
プログラム
コメント:0
トラックバック:0
プログラムと前提
このソフトウェアを使うためにはライブラリ○○が必要になります。
このソフトウェアをビルドするにはコンパイラ○○が必要になります。
このソフトウェアはライブラリ○○のバージョンが○○以上でないと動きません。
このソフトウェアはOS○○でないと動きません。 使いたいソフトウェアにこのような条件があった場合、あなたならどうしますか? 自分のPC環境がこの条件を満たしていなかった場合、前提を整える工程を余計に必要とするでしょう。あなたはそれをこなしてでもそのソフトウェアを使いたいと思いますか?ゲームだったらどうしますか?
この答えは人によって変わります。しかし、そこで「やっぱりやめた」と思ってあきらめる人は大抵において存在します。そして、その行為が面倒な程にその割合は多くなるでしょう。
だから、我々製作者はその苦労を理解し、ユーザがそのソフトウェアを使いはじめられるように配慮しなくてはならないでしょう。それが使えるようにするためのバッチ処理を行うプログラム、いわゆるインストーラが存在する意義です。
このインストーラ、環境変数を追加したり、指定のファイルを指定のディレクトリに置いたりしますが、一番面倒なのは依存関係を解決するための処理、すなわち自分が作ったプログラムとは別のプログラムのインストールです。権利関係とかマナーとかそういうものが絡んでくるので、面倒です。
方法は、
・ネットワークに接続して、プログラムのアーカイブをダウンロードする
・アーカイブ内にプログラムを同梱する
・アーカイブが特定の位置にあることを前提とし、ソフトウェアそのものは自分で用意してもらう
大概において、これら3つの解決方法のどれかが使われます。どれ害意と位置がいいにいえる手段は無いため、用途にあった手段を選びましょう。
・
ネットワークに接続して、プログラムのアーカイブをダウンロードするアーカイブは小さくなり、依存関係を解決するための行程はプログラムが全て行ってくれます。ただしオフラインでは使えませんし、リンク先の保証が出来るとは限りません。
・
アーカイブ内にプログラムを同梱するファイルサイズは大きくなりますが、オフラインでも使えますし、一時フォルダを使う必要もありません。割と一般的な方法です。
・
アーカイブが特定の位置にあることを前提とし、ソフトウェアそのものは自分で用意してもらう ユーザに一手間かけさせる事になりますが、ファイルサイズは小さくなります。そのソフトウェアを持っていて、かつそれをインストールする可能性が高ければ、処理を飛ばす可能性も高いので効率的です。いい目で見られるかどうかはともかく。
この手のインストーラ自体、ある程度規模が大きくなってきてから必要となるものですし、最近のOSには比較的必要な機能が最初から入っている(はず)です。そのため、ここで説明しても一部の人を除いては参考にならないでしょう。その一部の人も分かりきっている可能性が高いので、余計参考にならない割合は多いでしょう。
マルチプラットフォーム+D言語はまだまだ面倒です。
2009/08/24
ただの日記
コメント:0
トラックバック:0
コンパイラって取り揃えたいよね
pixivで「GNU」を検索すると2件出ました。
GNUのマスコットは愛嬌があって、私は気に入っているのですがどうなのでしょうか。
さて、実際にアプリケーションを動かすためにはバイナリファイルがある必要があります。Windows等、バイナリを直に送っても大抵において動く場合はともかく、大抵においてはソースコード等の入ったアーカイブをダウンロードして、makeを使ってビルド出来るようになっています。
そしてこのmake、引数によって動作を変えることも可能ですし、ディレクトリにあるmakefileを勝手に探して使用します。ファイル指定が必要無いというのは派手に便利です。
2009/08/11
ゲーム製作
コメント:0
トラックバック:0
東方星蓮船やってみた
少し前に、Web体験版が出たということで東方星蓮船をダウンロードして、インストールして、遊ぼうとしました。
動きはしましたが、ものすごく遅くてとても出来たものではない、と。
もちろんゲームのせいではなく、実行環境が整っていないだけなんですけどね。
WineD3D_ChoosePixelFormat Can't find a suitable iPixelFormat このまま泣き寝入りするのも日曜プログラマ見習いとして格好悪いので、ソースを辿って原因を探ってみることにしました。既に誰かが解明しているはずですが、読めませぬorz
このエラーを吐く箇所は、wined3d/context.c内の関数WineD3D_ChoosePixelFormatです。
それに加えて、
Falling back to ChoosePixelFormat as we weren't able to find an exactly matching pixel formatというメッセージが出されることもあります。
この場合
findCompatibleがtrueなのですが、そこで再構成されてもまだエラーを起こす場合が結構あるようです。そもそも元のピクセルフォーマットがどうなっているのかを調べる必要があるのであって、デバッグ情報をコンソールに吐き出す必要があるのですが、
TRACE("略 抜かりねぇな。
オープンソースプロジェクトなので私のような見習いにも親切なソースコードを心がけておられるようです。これは私も見習わなくてはなりませんね。
恐らくこれはデバッグ時にのみ実行される関数ですので、デバッグ用にコンパイルする必要がありそうです。後はその方法。
こうして考えると結局未解決のまま終わっている話題が多いですね。これはまずい。
2009/08/07
ただの日記
コメント:0
トラックバック:0
奥さんgtkDですってよ
最近スクリプトしか書いていません。
シェルスクリプトもいいのですが、私はRubyの方が好きです。
スクリプト言語が快適に動くのもハードウェアの進化があるからこそです。万歳。
スクリプト言語は手軽ですが、多少込み入った処理を記述すると処理が重くなってしまうので、自由度と実行速度を兼ね備えたD言語を使ってプログラムを書きます。
ついでにGUIを持つプログラムも作りたいところですが、ウィンドウシステムに共通する記述方法が無いので、GUIライブラリを使って記述する必要があります。
今回私が使うライブラリはgtkDです。
LGPLというライセンスを使っており、しかもコードをプログラムの中に組み込むため、コピーレフトの規約に基づきソースコードを公開し、それを扱う事を妨げないようにする必要があります。あとテキストへの記述とか。
GTK+の機能をD言語から楽に使えるようにしたもので、クラスとして扱えるので楽そうです。まだライブラリのソースコードとサンプルプログラムを見ただけなのでそこまで詳しくは分かりませんが。
ちなみにgtkD1.2ですが……。
WindowsとDMDではコンパイル不可能でした。 問題点は
core.sys.posix.sys.typesモジュールにて、windows系統のaliasが無いため、結果的に存在しない型を扱っているようになるわけです。かといって
fdopenはそのモジュールに定義されているため、回避するわけにも行かないのです。
……ここまで書いてから言いますが、この手のライブラリはファイルが大きくなるんですよ。基礎部分だけで1MB超とかのライブラリも普通に存在しますし。ファイルサイズが大きいと、ユーザーによってはダウンロードが面倒になりますし、HDDも圧迫します。さらにラッパライブラリは関数オーバーヘッドが増えることにより、実行速度もわずかながら(しかも無駄に)遅くなります。スマートな手法ではないのは分かっているのですが、作業効率を考えると導入すべきかせぬべきか迷うところです。
はざまに揺れながらのいたちごっこ乙
2009/08/06
プログラム
コメント:0
トラックバック:0