鏑矢の憂鬱1999年12月後半
透明1ドットイメージ
 
1999/12/22 (Tue)
・どうも、鏑矢です。まー皆さん知ってると思いますが、かなゆ〜の復活です。毎日毎日、プログラミングのこととかを書いたり、皆さんに送っていただいた質問に答えたりします。金菜さんじゃなくわてが答えるってことで、自由度高いです(爆)。……でもなんとなく恥ずかしいのは気のせい?
 
・えっと、実は今日はプログラミングしてないんです。でも投稿があったんでそれを載せましょー。もしなかったらいきなりお休みだったかも……(汗)。まずひとつめ。
 
透明1ドットイメージ
透明1ドットイメージ
 えーと、GCCはg++を使うとデフォルトがC++になるんですけど、もう知ってますよね。
透明1ドットイメージ
透明1ドットイメージ
 
・情報ありがとー。っていうかずっと C++ としてしか使ってませんでした(爆)。もともと C++ 使いたいから cc じゃなくて gcc を使ったってところもあるし。これって前に「 -c が【C言語で】ってゆースイッチだと思った」とかの話かな?
 
・もひとつツッコミよん。
 
透明1ドットイメージ
透明1ドットイメージ
 こんにちは。
 moguと言います。
 久しぶりに覗いたら変わってたのでちょっとビックリです。
 
 さて、質問があります。(22日からだから大丈夫かな?)
 VC++で英語、日本語用のアプリケーションを作成しています。
 現在は別々に作成していますが、これを切り替え式にしたいと思っています。
 それで、リソースの切り替えを簡単にできる方法が無いのか調べています。
 最悪は*.rcファイルの差し替えをしようと思ってますが、できれば同時に編集し、ビルド時に切り替えればと思います。
 何か良い方法があれば教えてください。
透明1ドットイメージ
透明1ドットイメージ
 
・こんにちはです。変わってたってどんくらい変わってたんだろう……。えっと、リソースのロケールについてははっきしいってよく分かりませんでした(汗)。リソースの右クリックメニューから【コピーの挿入】を選んでターゲットの言語を選ぶと、ひとつのIDに複数言語のリソースを割り当てることができます。こうすることでひとつのアプリに複数言語のリソースを組み入れられて、OSのロケール設定にあわせて自動的に選択されるんだそうです。
 
・「だそうです」ってのは、実はうまくいかなかったから(汗)。コントロールパネルの「地域」を変えれば自動的に変えられると思ったんだけど、そうなりませんでした。うーむ。もしテスト用のターゲットがあればそれで試してくださいです。主な情報源は、MSDNの「リソースに変更を加えてコピーする」とかナレッジベースの J041143 とか。あとリソースを地域別DLLに封じ込める方法とかもあります。これはMSDNの「テクニカル ノート 57: MFC コンポーネントのローカライズ」を読んでみてください。
 
・おー、のっけから歯切れ悪い解答だ(爆)。まーうちらしいかも。これからも質問ばんばん送ってねー。
 
・でわまたっ!
透明1ドットイメージ
 
1999/12/23 (Wed)
・やっほー。今日は DirectX をちょっと試してみました。
 
・ってゆーか実際に試す段になるまで結構時間かかりました(汗)。とりあえずオフィシャルページにあるチュートリアルをダウンロードして、テストプロジェクトを作ってコンパイル。しかーし無茶苦茶変なコンパイルエラー発生。原因はVC6付属のインクルード&ライブラリファイルに古い DirectX のものがあったからだった……。優先順位を上げることで解決。
 
・しかし、コード見てもなーんか分かんないです。いやまーゆっくりじっくり見れば分かるだろうけど、量多いし憶えなきゃいけないこと多くて結構大変。とりあえずCOMインターフェイスの知識があるだけでも良かったかもしんない。とりあえずゆっくり調べていくことにしましょう。
 
・ちなみに最終目的は、ゲームの作成。とあるシューティングゲームの構想があるんで、1ヶ年計画ぐらいで作ってみようかなーと。あとえーかげん DirectX は知っておかないといかんかなと思って。今度 OpenGL も試してみましょう。んでもダウンロードすんのめんどいなー、なんかのCD−ROMにSDK入ってないかな。
 
・あとぷらとわ1話作成。今回のバージョンが終了するまでにまだ結構掛かる……なんかのんびりしすぎって感じもするけど、ま、そんなにあっさりマスターできるもんでもないし、それもいーんじゃないかなーとか。うん。
 
・でわまたっ!
透明1ドットイメージ
 
1999/12/24 (Fri)
・今日は OpenGL とかで遊んでました。
 
・日記の方で教えていただいたページで OpenGL for Win32 SDK をダウンロードして(マイクロソフトにあるんですねぇ)、こちらのページのサンプルを試してみました。 DirectX に比べて、導入が楽だったなー。
 
・中身的にはまだちゃんと理解してないんでよく分かんないです(汗)。とりあえず両方とも使ってみて、知識深めようと思ってます。でもやっぱ難しそうだなー。どっちもアニメーションフリップの仕組みがよーわかんないんで調べてみないと。メッセージ処理を阻害しないでよくあれだけなめらかに動くもんだなー。
 
・あと、ちょっとHTML関係のプログラムに興味あったんで、 Inside Windows の1997年9月号に載ってた MiniWWW とゆーのを試してみる。なんか、エラーもなしにページの読み込みが途中で終わっちゃうことがあるのがちょっと不安。何が悪いのかなー。
 
・ホントはたすかぶとかのバージョンアップが先なんだけど、どーも面倒で(汗)。それよか、新しいアプリ作った方が楽しそう。それにあわせてKTLを強化して、それをベースにバージョンアップするっていうのが結構手っ取り早いかもしんない。やってみるかなー。
 
・でわまたっ!
透明1ドットイメージ
 
1999/12/25 (Sat)
・今日はこのツッコミから!
 
透明1ドットイメージ
透明1ドットイメージ
 どうも、キャリコです。
 
 質問ではありません。(^_^;;
 
 
 Java(狂)信者として一言。
 
>今日は OpenGL とかで遊んでました。
 
 OpenGL は Java でもできますよぉ〜!
 
 ちなみに OpenGL を使用したシューティングゲーム(Freeware)もあります。
<@see ABA Games http://www.asahi-net.or.jp/~cs8k-cyu/ >
 
 
>あと、ちょっとHTML関係のプログラムに興味あったんで、
>Inside Windows の1997年9月号に載ってた MiniWWW とゆーのを試してみる。
 
 そりゃ HTML やのーて HTTP でんがなっ!
# HTML 関係って言ったら HTML Parser とか構文解析の方になるのでは?
 
 
>なんか、エラーもなしにページの読み込みが途中で終わっちゃうことがあるのが
>ちょっと不安。何が悪いのかなー。
 
 ちなみにそのテストはローカルで行ったのでしょうか?
 もし、外部(Internet)に対してテストを行ったのであれば、サーバ側がコネクションを閉じてるのかもしれません。
 もしそうであれば、ローカルな環境でテストされた方が良いと思います。
 
 あとは MiniWWW というプログラムがどのようなリクエストをしているか調べるのも良いと思います。
 もしかしたら HTTP バージョンを含まないリクエストを行っているのかもしれません。
 
 ちなみに私、Java で Download Manager 作ってます。(まだ公開してませんが)
よろしければご覧ください。
<@see [ALiCE in wired] development room http://www.freepage.total.co.jp/calico/index.html >  
 
 ページの趣旨にそぐわない内容ですいません。m(_ _)m
 
 それでは失礼します。
透明1ドットイメージ
透明1ドットイメージ
 
・おー、助言助かります〜。OpenGL に Java 用があるとは。やっぱ知識として知っとくんだったら OpenGL かなー。でもゲーム作ったり、ページの人気上げるんなら DirectX って気も(爆)。とりあえず両方勉強しとこー。「HTMLなアプリ」は一応HTML構文解析が中心。でも昨日テストしたのはHTTPの部分だけ。微妙微妙。ちなみに MiniWWW は特定のアドレスの index.html ページをただ読み込むものです。
 
・質問! 「テストはローカル」ってことは、うちのPCにウェブサーバーを入れるってことでしょーか。どーゆーのを入れればいいんでしょう。なんかむずかしそ……。あと昨日のエラーは単に OutputDebugString() がうまく出力してないだけでした(汗)。ファイルに出したらちゃんと全部読み込んでました。ご迷惑かけたです。
 
・で、今日はたいしてプログラミングしてないです(汗)。とりあえず適当なファイルを読み込んで保存してみたり。結構道は遠いんで、のんびりいくつもりです。文字列検索とかって苦手な分野だし(汗)。あと実験のもえーかげんしないとなー。
 
・でわまたっ!
透明1ドットイメージ
 
1999/12/26 (Sun)
・はひー、とりあえず今27日の1時半だけど、とりあえず昨日載せようと思ってたのだけ。まずはキャリコさんからのお便り。
 
透明1ドットイメージ
透明1ドットイメージ
 どうも、キャリコです。
 
 またも質問ではありません。(^_^;;;
 
>OpenGL に Java 用があるとは。やっぱ知識として知っとくんだったら >OpenGL かなー。
>でもゲーム作ったり、ページの人気上げるんなら DirectX って気も(爆)。
 
 あ、ちなみに Windows 用の Java には OpenGL を使用するライブラリと DirectX を使用するライブラリの 2 種類が提供されています。
<@see http://java.sun.com/products/java-media/3D/index.html >  
>質問! 「テストはローカル」ってことは、うちのPCにウェブサーバーを入れるって
>ことでしょーか。どーゆーのを入れればいいんでしょう。
 
 王道は Apache だと思いますが、設定はテキストファイルを書き換えて行わなけ ればならないので結構面倒かもしれません。
 ちなみに AN HTTPD なら設定方法を紹介したサイトもたくさんあるのでオススメ です。
<@see Apache http://www.apache.org/
  AN HTTPD http://www.st.rim.or.jp/~nakata/ >
 
# Java なら W3C の Jigsaw や Jetty といったものがあります。
# <@see Jigsaw http://www.w3.org/Jigsaw/
#  Jetty http://www.mortbay.com/software/Jetty.html >
 
 あと HTML ファイルを簡易的に解析するのなら strtok を使用すると良いかもしれません。他には、HTML ではありませんが IBM が提供している XML for C++ というものもあります。
 HTML も XML も基本的な構文は同じですので、参考になると思います。(たしかソースコードも配布されているハズです)
<@see XML for C++ http://www.alphaworks.ibm.com/tech/xml4c
  XML for Java http://www.alphaworks.ibm.com/tech/xml4j >
 
 Java の話ばっかりしてすいません。
# でもホントにいいんですよ java って。(T_T) < ナゼ泣く。
 
 それでは失礼します。
透明1ドットイメージ
透明1ドットイメージ
 
・どうもですー、で、とりあえず HTTPd を使ってみました。お”、家の中のファイルがホームページのように! なんか感動。ところがなぜか、127.0.0.1 経由だと MiniWWW のテストアプリがうまく動かないのです(泣)。エラーチェックは全部通るのに、recv() で固まっちゃって、数分間帰ってきません。で、帰ってきたら何事もないように振舞うし。とりあえずテストクラスはこちら。
 
 


class CPageLoader
{
	enum
	{
		PORT_NO = 80
	};

	SOCKET m_uiSocket;
public:
	CPageLoader()
		: m_uiSocket( 0 )
	{
		WSAData stData;
		int iErr
			= WSAStartup( MAKEWORD( 1, 0 ), &stData );
		if( iErr != 0 )
			OutputError();
		m_uiSocket = socket( PF_INET, SOCK_STREAM, 0 );
		if( m_uiSocket == INVALID_SOCKET )
			OutputError();
	}

	~CPageLoader()
	{
		closesocket( m_uiSocket );
		WSACleanup();
	}

	void Load
		( const char *const p_pchUrl
		, const char *const p_pchLoadFile
		, std::ostream &p_rcOStrm )
	{
		DWORD dwIp
			= GetIpAddress( p_pchUrl );
		Connect( dwIp );
		Loop( p_pchLoadFile, p_rcOStrm );
	}

private:
	DWORD GetIpAddress(  const char *const p_pchUrl )
	{
		DWORD dwIp
			= inet_addr( p_pchUrl );	//ドット形式のアドレスをIPアドレスへ変換。
		if( dwIp != INADDR_NONE )	//うまくいったら
			return dwIp;	//そのまま返します。
		//	うまくいかなかったら変換。		
		hostent* pstHost;
		pstHost = gethostbyname( p_pchUrl );	//ホスト名から IP アドレスに変換。
		if( pstHost == NULL ) 
			OutputError();

		return *( reinterpret_cast< DWORD * >( pstHost->h_addr ) );
	}

	void Connect( DWORD p_dwIp )
	{
		SOCKADDR_IN stAddr;
		stAddr.sin_family = AF_INET;	//TCP/IPを選択
		stAddr.sin_port = htons( PORT_NO );	//ポートの指定
		stAddr.sin_addr.s_addr = p_dwIp;	//IPアドレスの指定
		int iErr
			= connect( m_uiSocket, (const struct sockaddr*)&stAddr, sizeof( stAddr ) );
		if( iErr != 0 )
			OutputError();
	}

	void Loop( const char *const p_pchFile, std::ostream &p_rcOStrm )
	{
		char pchGetComm[256];
		sprintf( pchGetComm, "GET %s\n", p_pchFile );
		int iRes
			= send( m_uiSocket, pchGetComm, strlen( pchGetComm ), 0 );
		if( iRes == SOCKET_ERROR )
			OutputError();
		int iSize = 0;
		char buf[4096];
		while( 1 )
		{
			iSize = recv( m_uiSocket, buf, 4095, 0 );	//ここで止まる……。
			if( iSize == 0 )
				break;
			if( iSize == SOCKET_ERROR )
				OutputError();

			buf[iSize] = '\0';
			p_rcOStrm
				<< buf
				<< std::flush;
		}
	}

	void OutputError()
	{
		throw( WSAGetLastError() );
	}
};

void Test()
{
	CPageLoader cPageLoader;
	std::fstream cFStrm( "Output.txt", std::ios::out );
	cPageLoader.Load( "www.justnet.ne.jp", "/index.html", cFStrm );
}

	
 
・なんか変なとこがあったら言ってね。ただし例外処理は除く(笑)。これはちょっと間違った実装方法ですね〜。
 
・てなことを書こうと思ってたんだけど再セットアップで遅れてしまいました。いやー、キャリコさんのメールとっととコピーしといて良かったです。ただ、もしかしたら今日明日休むかも(汗)。VCのキーカスタマイズしないとなー。
 
・でわまたっ!
透明1ドットイメージ
 
1999/12/27 (Mon)
・いや〜、昨日はごめんです。だいたい復旧したんだけど、まだ IME 周りが整ってないから日本語入力が大変で・・・<ほら、これ、いつもと違うでしょ。ま〜そんなこたともかく、今日もお便りからよん。
 
透明1ドットイメージ
透明1ドットイメージ
 どうも、キャリコです。
 
 久しぶりに C++ のソースコードを見て「懐かしい」気分になってしまい、もう C++ には戻れない体になっていることを実感しました(笑)。
 
>ところがなぜか、127.0.0.1 経由だと MiniWWW のテストアプリがうまく動かないのです(泣)。
 
 まずプログラムとは無関係な部分なのですが、Windows ディレクトリ以下に「HOSTS.SAM」というファイルがあると思いますので、これを同じディレクトリにコピーして「HOSTS」というファイル名に変更してください。
 
 そして、このファイルに以下の内容が記載されているかを確認してください。
--
127.0.0.1 localhost
--
 おそらくこれは記載されていると思います。
 
# ちょっとした Tips ですが、このファイルに以下の内容を付け加えると
# www2.justnet.ne.jpへのアクセスが自マシンの HTTPd に送られるようになる
# ので、デバッグなどに使用できます。
# --
# 127.0.0.1 www2.justnet.ne.jp
# ---
 
 多分この「HOSTS.SAM」->「HOSTS」は関係ない可能性大です(笑)。
 
 
 次にプログラムの部分ですが、鏑矢さんが使用されている OS は Windows 98 だと思いますので、
--
#pragma comment(lib, "wsock32.lib")
#include <winsock.h>
 :
 :
int iEr = WSAStartup( MAKEWORD( 1, 0 ), &stData );
--
	
の部分を
--
#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
 :
 :
int iEr = WSAStartup( MAKEWORD( 2, 2 ), &stData );
--
に変更した方が良いかもしれません。
しかし、これも関係ない可能性大です(笑)。
 
 
 最後に、一番関係があると思われる部分は以下の行です。
--
sprintf( pchGetComm, "GET %s\n", p_pchFile );
--
 
 これは、先日私が言いました
--
もしかしたら HTTP バージョンを含まないリクエストを行っているのかもしれません。
-- の部分です。
 
 
 現在一般的に使用されている HTTP/1.1 の仕様(RFC2616)では、以下のように規定されています。
--
Request = Request-Line
          *(( general-header
          | request-header
          | entity-header ) CRLF)
          CRLF
          [ message-body ]
--
Request-Line = Method SP Request-URI SP HTTP-Version CRLF
--
CR = <US-ASCII CR, carriage return (13)>
LF = <US-ASCII LF, linefeed (10)>
SP = <US-ASCII SP, space (32)>
--
	
 
すなわち以下の様にしなければいけません。
--
sprintf( pchGetComm,
         "GET %s HTTP/1.1\r\n"
         "\r\n", p_pchFile );
--
	
 
 加えて、HTTP/1.1 では "Host" リクエストヘッダを必ず送信しなければいけません。
--
Host = "Host" ":" host [ ":" port ]
--
	
 よって最終的に以下の様になります。
--
sprintf( pchGetComm,
         "GET %s HTTP/1.1\r\n"
         "Host: %s\r\n"
         "\r\n", p_pchFile, <ホスト名が格納されている文字列変数> );
--
	
なお HTTP に関する RFC は以下の URL で検索、入手できます。
--
RFCFIND http://netnews.to/rfc/
RFC in Japanese http://www-kn.sp.u-tokai.ac.jp/~torao/rfc/
--
 
# あと、私が C++ をやっていたときに参考にしていた書籍は、ソフトバンクの
# 「WinSock2.0プログラミング」です。
# ISBN4-7973-0688-2, \5,800- + TAX
 
 すごく冗長な説明になってしまって申し訳ないです。m(_ _)m
 
 
 それでは失礼します。
透明1ドットイメージ
透明1ドットイメージ
 
・うおー、ありがとうです! 動きましたよ!! 原因はやっぱ GET で Host を渡していなかったからでした。いや〜、やっぱサンプル適当に使ってるだけじゃダメですね(汗)。RFC しっかり読んでみます。それか本買ったほうが早いかも。1冊あると安心だし。
 
・あと HOSTS.SAM の Tips 面白いですね。これ届く前に HOSTS.SAM の方は試していたんですが、そのときには「あ〜、わざわざ 127.0.0.1 なんて打たずに localhost でいいんだ」くらいにしか思ってませんでした。これは便利かも。
 
・んでもひとつよん。
 
透明1ドットイメージ
透明1ドットイメージ
 追加です。
 
 以下の部分ですが、バッファリングを行っていないのでリクエストが完全には送信されない可能性があります。
--
int iRes =
    send( m_uiSocket, pchGetComm, strlen( pchGetComm ), 0 );
if( iRes == SOCKET_ERROR )
    OutputError();
--
	
 よって以下の様に変更した方が良いと思います。
--
int iLength = strlen( pchGetComm );
int iRes = 0;
do {
    iRes = send( m_uiSocket, pchGetComm, iLength, 0 );
    if( iRes == SOCKET_ERROR ) {
        OutputError();
    pchGetComm += iRes;
    iLength -= iRes;
} while (iLength > 0);
--
	
 
 ちなみに
 
>これはちょっと間違った実装方法ですね〜。
 
 とのことですが、具体的にはどこが間違っているのでしょうか?
 
 このソースコードでは同期的に処理を行っていますが、これを非同期にしなければいけない、ということでしょうか?
 
 個人的な考えですが、同期処理の方が処理が一直線に流れていくので、処理内容が理解し易くなると思います。
 
 あるいは send() や recv() でブロッキングされて困る、というのであればワーカースレッドを起動してそのスレッドで処理させれば良いので、わざわざ非同期にする必要はないように思います。
# ハズしてたらすいません。m(_ _)m
 
 それでは。
透明1ドットイメージ
透明1ドットイメージ
 
・なるほど、送信コマンドが全部食われるまで送りつづけるわけですね。こーゆー細かい部分まで憶えるのは大変かもな〜。ま、試さなきゃ憶えられないんだし、今はいろいろしてみましょー( あと if( iRes == SOCKET_ERROR ) { の中カッコはいらないですよね)。
 
・「間違った」のは例外処理のとこです。あーやってただ数字だけ投げてると受けるほうは死ねます(笑)。Winsock エラーに特化した std::runtime_error 派生クラスを投げるのが正解でしょう。あと throw() をシグネィチャーに付けないと。同期問題は、ワーカースレッドなら「知ってる」んでそのほうが楽っぽい(爆)。
 
・まー結局のところ、もっと RFC とかのドキュメントを読まないとあかんかも。んでも久々にやりがいある分野かもしんない。あ、でも実験とっとと終わらせといたほうがいいかも(汗)。
 
・でわまたっ!
透明1ドットイメージ
 
1999/12/28 (Tue)
・今日はあんまプログラミングしてません(汗)。とりあえず、実験用プログラムの下準備。
 
・あ、知らない人用に言っとくと、実験っていうのは「電子情報学実験」とゆ〜、大学の授業のことです。プログラムを組んだりして結果をレポートにまとめて提出します。今回の実験は1月13日の提出のもの。もともとソースコードはあるんだけど、いろいろ手直ししないといけなかったり。ってゆ〜かそれが楽しい(爆)。
 
・実験の内容は、音声データを窓関数に掛けて FFT 掛けて gnuplot で出力して「何を言ってるか」を判別すること。で、そのプログラムの中では
typedef struct {
    double re, im;
} COMPLEX;
	
ってゆー構造体で複素数を表してます。知ってる人は知っての通り、標準 C++ ライブラリにこれとほとんどおなじクラステンプレート std::complex があるんで、これに移行するために今日は std::complex のテストしてました。
 
・しかし、いまいちわかんないとこもあり。これを std::log() とかに掛けたときの振る舞いがよくわかんないな〜。複素数で log を求めるってことの意味がいまいちよくわかってないのかも。コードが見やすい SGI 版で……と思ったら std::complex って STL には含まれてないんだよね(汗)。ま、時間はまだあるし、のんびり見てこっと。
 
・でわまたっ!
透明1ドットイメージ
 
1999/12/29 (Wed)
・今日も実験プログラムをちょこっと。ところがところが、これがかなりの難敵であることが判明。 FFT ってことでそのロジックの理解や、文法の古さ、1行になるべく詰め込もうとする書式、そしてグローバル変数と悪夢って感じ(泣)。ホント言うと、実験には「プログラムの解析」は必要ないんで、時間がやばくなったらパスすべきだけど、でもこれできないとなんかつまんない(爆)。
 
・尺八郎さん、ゆっくりでい〜ですよ〜。
 
・でわまたっ!
透明1ドットイメージ
 
1999/12/30 (Thu)
・今日も引き続き実験プログラミング。やっとこさ、全体像が掴めました。実行結果も、学校の方でしたのと同じだったんでひと安心。それにしても、グローバル変数は使ってるし、 malloc() しといて free() しないし、変数名は意味不明だし、ひとつ関数を置いてから再帰呼び出ししてるし、なかなか大変だったです。
 
・ま、こういうのも結構重要な経験だし、 FFT 自体は理解しとかないとね。これからどんどんリファインさせて、実際にどういうアルゴリズムで動いているか把握したいです。ただ2重ループが多いんで、 STL アルゴリズムにそのままかませるのはちょっと難しいかも。
 
・でわまたっ!
透明1ドットイメージ
 
1999/12/31 (Fri)
・今日はお休みぴょん。明日もたぶん。
 
 
(C)KAB-studio 1999 ALL RIGHTS RESERVED.