四方山話 ( 2010/08/01 - 2010/12/31 )


このページは、私が思いついた時に(だから毎日ではない)、思 いついたことを(だからコンピュータだけの話ではない)、思いついたなりに (だから日本語むちゃくちゃ)徒然と書き綴るページです。



2010/12/29 (Wed)
多分これが今年最後の更新。しかし、暮れも押し迫ったこの時期にいった い何をやっているんだ...他にすることがないんかい!いや大量にある、それも 処理できないくらい大量に(泣)。が、これもやってしまわないといかんもので...

さてプログラムの設定情報については、Unix系OS だと /etc 以下のファイ ルとか $HOME のドットファイルとかに保存されているということが多いような 気がする(最近は Unix系OS をいじってないので間違ってるかもしれません)。 で、Windows(Win32) ではレジストリに保存するのを MS は推奨(強要?)して います。が、その昔(Win16)では ini ファイルに保存されていました。で、プ ログラムの設定情報のバックアップなどを考えるとレジストリより ini ファ イルのほうが便利だと思うんですよね。多分、だからこそ、 FFFTP のオプションにも 設定を ini ファイルに保存するというのがあるんだと思っています。という ことで、MS に何を言われても ini ファイルを使いたいと思います。で、ini ファイル関係の関数一覧。詳しくは link 先を参照のこと。

UINT GetPrivateProfileInt( LPCTSTR, LPCTSTR, INT, LPCTSTR )
指定した ini ファイルの指定したキーの設定値(整数)を読み込む。 返り値は ini ファイルから読み込んだ設定値(整数)。ini ファイルに指定 したキーの設定が見つからない場合には default 値(第3引数で指定)を返す。
DWORD GetPrivateProfileSection( LPCTSTR, LPTSTR, DWORD, LPCTSTR )
DWORD GetPrivateProfileSectionNames( LPTSTR, DWORD, LPCTSTR )
DWORD GetPrivateProfileString( LPCTSTR, LPCTSTR, LPCTSTR, LPTSTR, DWORD, LPCTSTR )
BOOL GetPrivateProfileStruct( LPCTSTR, LPCTSTR, LPVOID, UINT, LPCTSTR )
BOOL WritePrivateProfileSection( LPCTSTR, LPCTSTR, LPCTSTR )
BOOL WritePrivateProfileString( LPCTSTR, LPCTSTR, LPCTSTR, LPCTSTR )
BOOL WritePrivateProfileStruct( LPCTSTR, LPCTSTR, LPVOID, UINT, LPCTSTR )
UINT GetProfileInt( LPCTSTR, LPCTSTR, INT )
DWORD GetProfileSection( LPCTSTR, LPTSTR, DWORD )
DWORD GetProfileString( LPCTSTR, LPCTSTR, LPCTSTR, LPTSTR, DWORD )
BOOL WriteProfileSection( LPCTSTR, LPCTSTR )
BOOL WriteProfileString( LPCTSTR, LPCTSTR, LPCTSTR )
Win.ini ファイルの指定したキーに対する設定値(文字列)を書き込む。 成功すると 0 以外の値を返し、失敗するか Win.ini ファイルのキャッシュを フラッシュすると 0 を返す。

そんなわけで、以下サンプルプログラムとか。ちなみにソース16行目はわ ざとで、ini ファイル内に存在しないキーの情報を指定した場合の動作を確認 するため。そもそも ini ファイルがない場合の動作も実験。その他の実験と か解説とかはまた後日。

D:\home\sample.ini
[COMMON]
IP=192.168.0.1
Port=80
Database=D:\\home\\data.mdb
sampleI01.cpp
 1: #pragma  comment( lib, "kernel32.lib" )
 2: #include <windows.h>
 3: #include <stdio.h>
 4: #define  INI_FILE_NAME "D:\\home\\sample.ini"
 5: #define  STRING_SIZE   30
 6:
 7: int main( int argc, char *argv[] )
 8: {
 9:     char  s[STRING_SIZE];
10:     DWORD i;
11:
12:     i = GetPrivateProfileString( "COMMON", "IP", "", s, STRING_SIZE, INI_FILE_NAME );
13:     printf( "%d : %s\n", i, s );
14:     i = GetPrivateProfileInt( "COMMON", "Port", 0, INI_FILE_NAME );
15:     printf( "%d\n", i );
16:     i = GetPrivateProfileString( "COMMON", "hoge", "", s, STRING_SIZE, INI_FILE_NAME );
17:     printf( "%d : %s\n", i, s );
18:     return 0;
19: }
コンパイル結果および実行結果
[D:\home] cl sampleI01.cpp
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

sampleI01.cpp
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:sampleI01.exe
sampleI01.obj

[D:\home] sampleI01.exe
11 : 192.168.0.1
80
0 :

[D:\home] ren sample.ini sample.bak

[D:\home] sampleI01.exe
0 :
0
0 :

[D:\home] 
2010/12/28 (Tue)
時間の関係上、前置きを端折りいきなり本題。プログラムを作成する際に 必要となったため、今回は変数の型について超簡易版のまとめ。ま、C 言語の 変数の型といえば、char/int/short/long/float/double/void という感じでし ょうか。(参考:Javaの場合)で、 Windows では MSDN の「 Windows Data Types」にある通り、いろいろな変数型が用意されています。 そんなわけで必要そうなところだけ備忘録、local cache としてまとめておき ます。残りは...時間を見つけてそのうち。あ、あと、「 Fundamental Types」なんかも参考のこと。
型名説明 ヘッダファイル
BOOLブール型 ( TRUE 又は FALSE ) WinDef.h
BOOLEANブール型 ( TRUE 又は FALSE ) WinNT.h
BYTEバイト型 - 8bit WinDef.h
CHAR8bit文字型(ANSI) WinNT.h
COLORREF色値(赤緑青 RGB) - 32bit WinDef.h
DWORD32bit符号なし整数 ( 0 〜 4294967295 ) WinDef.h
DWORD3232bit符号なし整数 BaseTsd.h
DWORD6464bit符号なし整数 BaseTsd.h
HANDLEオブジェクトへのハンドル WinNT.h
HRESULTCOMインタフェースの返値 WinNT.h
HWNDウィンドウへのハンドル WinDef.h
INT3232bit符号付き整数 ( -2147483648 〜 2147483647 ) BaseTsd.h
INT6464bit符号付き整数
( -9223372036854775808 〜 9223372036854775807 )
BaseTsd.h
LONG3232bit符号付き整数 ( -2147483648 〜 2147483647 ) BaseTsd.h
LONG6464bit符号付き整数
( -9223372036854775808 〜 9223372036854775807 )
BaseTsd.h
LPBOOLBOOL変数への far ポインタ WinDef.h
LPBYTEBYTE変数への far ポインタ WinDef.h
LPDWORDDWORD変数への far ポインタ(注1) WinDef.h
UCHAR符号なしCHAR WinDef.h
UINT符号なしINT
( 0 〜 4294967295 )
WinDef.h
UINT32符号なしINT32
( 0 〜 4294967295 )
BaseTsd.h
UINT64符号なしINT64
( 0 〜 18446744073709551615 )
BaseTsd.h
WCHARUnicode文字 - 16bit WinNT.h
WORD16bit符号なし整数
( 0 〜 65535 )
WinDef.h
2010/12/27 (Mon)
先に Winsockを使ったネットワークプログラムを作成しましたが、MSDN の .NET 開発をナナメ読みした結論として、.NET Framework を使ってもネッ トワークプログラムは作れるみたい。つまり、 namespace System.Net.Sockets を使えばいいらしい。で、 System.Net.Sockets の Socket クラスの解説のページに VC++ の サンプルプログラムLocal Cache) が載ってたので、そのまんまパクってコンパイルしてみた。
[D:\home] cl /clr sampleM01.cpp
Microsoft(R) C/C++ Optimizing Compiler Version 16.00.30319.01
for Microsoft(R) .NET Framework Version 4.00.30319.1
Copyright (C) Microsoft Corporation.  All rights reserved.

sampleM01.cpp
sampleM01.cpp(17) : warning C4947: 'System::Net::Dns::Resolve' : 古い形式に設定
されています。
        メッセージ: 'Resolve is obsoleted for this type, please use GetHostEntry
 instead. http://go.microsoft.com/fwlink/?linkid=14202'
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:sampleM01.exe
sampleM01.obj

[D:\home] sampleM01.exe www.kantei.go.jp
Default HTML page on www.kantei.go.jp:
HTTP/1.1 200 OK
Date: Sun, 26 Dec 2010 14:32:26 GMT
Server: Apache
Last-Modified: Fri, 24 Dec 2010 13:35:12 GMT
Accept-Ranges: bytes
(以下、省略)

やっぱり HTTP の改行コードは \r\n が正解のようですね。で、コンパイル で Warning は出ましたが、問題なく動くようです。んが、やっぱ気になるので メッセージ通り http://go.microsoft.com/fwlink/?linkid=14202 を見に行ってみました。 そうしたらこれまたメッセージ通り Resolve は Obsolete され、代わりに GetHostEntry を使うようです。だったら webpage も update しておいてくれ ればいいのに...

Resolve から GetHostEntry に
16: //   hostEntry = Dns::Resolve( server );
17:    hostEntry = Dns::GetHostEntry( server );
コンパイル結果
[D:\home] cl /clr sampleM01b.cpp
Microsoft(R) C/C++ Optimizing Compiler Version 16.00.30319.01
for Microsoft(R) .NET Framework Version 4.00.30319.1
Copyright (C) Microsoft Corporation.  All rights reserved.

sampleM01b.cpp
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:sampleM01b.exe
sampleM01b.obj

[D:\home] 
2010/12/26 (Sun)
このところ休みは引き籠って終日プログラム作成。その割には成果が上が っていないような...うーん、困ったものだ。とはいっても地道にやるしか。 気長に...と言っているほど時間的余裕があるわけではないので、とにかく、 試行錯誤で進めるしかない。今回は前回で気になったことをちょこっと調べて みた結果。まずコンパイル時のオプション /clr と/FU について。 /clr は「共通言語ランタイム(CLR:Common Language Runtime)の機能 を使用する」という意味で、.NET Framework を使用する際に指定する...とい う理解で正しいのかな。 /FU は source で #using ディレクティブを使うのと一緒のことらしい。
[D:\home] cl /help
(以下、一部抜粋)
                             -コードの生成-

/clr[:option] 次のオプションが指定される場合、共通言語ランタイム用にコンパイルする:
    pure - ネイティブな実行可能コードではなく、IL のみの出力ファイルを作成する
    safe - IL のみの検証可能な出力ファイルを作成する
    oldSyntax - Visual C++ 2002/2003 からのマネージ拡張の構文を受け入れる
    initialAppDomain - Visual C++ 2002 の最初の AppDomain 動作を有効にする
    noAssembly - アセンブリを生成しない

                              -プリプロセッサ-

/AI<dir> アセンブリ検索パスに追加する
/FU<file> アセンブリやモジュールを強制的に追加する
/C コメントを削除しない                 /D<name>{=|#}<text> マクロを定義する
/E stdout に前処理する                  /EP stdout に前処理する、#line なし
/P ファイルを前処理する                 /Fx 挿入コードをファイルにマージする
/FI<file> 必ず使用されるインクルード ファイル名を指定する
/U<name> 定義済みのマクロを削除する     /u 定義済みのマクロをすべて削除する
/I<dir> インクルード検索パスに追加する  /X "standard places" を無視する

/FU system.dll というのは結局 source に #using <system.dll> と書くのと同じだから、サンプルプログラムNo.d01 だと1行目あたりに #using <system.dll> を書いておけば、コンパイル時に /FU system.dll を指定する必要はなかったんだね...で、source で system.data.dll を #using しているから、/FU system.data.dll も必要なかったと。ま、別に指定し ても何の問題もないと思いますけど。余談ですけがうちの Win7:64bit で は System.dll とか System.Data.dll は「C:\Windows\Microsoft.NET\」以下 にありました。次は、gcnew を new にしたらどんなエラーが出るかという実 験。

gcnew を new に
 8:     OleDbConnection ^oCNN
 9:         = new OleDbConnection(
10:                 "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\\home\\data.mdb;" );
11:     OleDbCommand ^oCMD
12:         = new OleDbCommand( "SELECT date FROM sample", oCNN );
コンパイル結果
[D:\home] cl /clr sampleDE1.cpp
Microsoft(R) C/C++ Optimizing Compiler Version 16.00.30319.01
for Microsoft(R) .NET Framework Version 4.00.30319.1
Copyright (C) Microsoft Corporation.  All rights reserved.

sampleDE1.cpp
sampleDE1.cpp(10) : error C2750: 'System::Data::OleDb::OleDbConnection' : 参照型
では 'new' を使用できません。'gcnew' を使用してください
sampleDE1.cpp(10) : error C2440: '初期化中' : 'System::Data::OleDb::OleDbConnect
ion *' から 'System::Data::OleDb::OleDbConnection ^' に変換できません。
        使用可能なユーザー定義された変換演算子がない、または
        アンマネージ型をマネージ型に変換できません。
sampleDE1.cpp(12) : error C2750: 'System::Data::OleDb::OleDbCommand' : 参照型で
は 'new' を使用できません。'gcnew' を使用してください
sampleDE1.cpp(12) : error C2440: '初期化中' : 'System::Data::OleDb::OleDbCommand
 *' から 'System::Data::OleDb::OleDbCommand ^' に変換できません。
        使用可能なユーザー定義された変換演算子がない、または
        アンマネージ型をマネージ型に変換できません。

[D:\home] 
2010/12/25 (Sat)
引き続き、Windows データベースプログラミング。理解できない範囲だけ ど、とにかく動くプログラムを作成。とにかく動けばいい!という考えが bug を生む最大原因なわけだが、最初はとにかく動くプログラムを作って、それを 足がかりに理解を進めたり改造したりするのがいつものパターンなので、今回 も同様に。そんなわけで、ADO.NET サンプルプログラム。いつものパターンで すが、間違っている部分もあるかもしれないと、先に言い訳しておきます。ち なみに解説が後回しなのもいつものパターン。「^」ってなんだ?「gcnew」っ てなんだろう...なるほど ...どういうことだ?(笑)ま、このへんは追々。
サンプルプログラムNo.d01
 1: #using <System.Data.dll>
 2: using namespace System;
 3: using namespace System::Data;
 4: using namespace System::Data::OleDb;
 5:
 6: int main( int argc, char *argv[] )
 7: {
 8:     OleDbConnection ^oCNN
 9:         = gcnew OleDbConnection(
10:                 "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\\home\\data.mdb;" );
11:     OleDbCommand ^oCMD
12:         = gcnew OleDbCommand( "SELECT date FROM sample", oCNN );
13:     oCNN->Open();
14:     OleDbDataReader ^oDR = oCMD->ExecuteReader();
15:     while( oDR->Read() ){
16:         Console::WriteLine( oDR->GetDateTime( 0 ) );
17:     }
18:     return 0;
19: }
コンパイル結果および実行結果
[D:\home] cl /clr /FU system.dll /FU system.data.dll sampleD01.cpp
Microsoft(R) C/C++ Optimizing Compiler Version 16.00.30319.01
for Microsoft(R) .NET Framework Version 4.00.30319.1
Copyright (C) Microsoft Corporation.  All rights reserved.

sampleD01.cpp
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:sampleD01.exe
sampleD01.obj

[D:\home] sampleD01.exe
1970/03/14 0:00:00
1979/03/20 0:00:00
1983/05/27 0:00:00
1970/11/28 0:00:00
1974/11/14 0:00:00
1979/03/27 0:00:00

[D:\home]
2010/12/23 (Thu)
引き続き、Windows プログラミング。今回は VC++ からデータベース、正 確に言えば MS-Access の DB を操作するプログラムを作ってみようと調べ始め る。VB、というか WSH とか Excel VBAから簡単に操作できたのでまあ VC++ でも簡単だろうと思っていたんだけど...とにかくネットでいろいろ調べてみた ところ、以前とは違う 結論 ADO.NET を使うのが今後のことを考えると一番よさそうだ、という結論に、 正しいかどうかはよくわからないが、達した。ちなみに ADO と ADO.NET とは 別物らしい。同じような名称なのに...紛らわしい。で、ADO.NET について MSDN などに目を通してみたが、現時点の私では非常に悲しいことだが理解するには 至らなかった...おわり。というわけにはいかないわけで、何が何でも DB を操 作せねばならない事情があり、先に進む足がかりを得るためにもまずは動くプ ログラムがどうしても必要なわけで。いろいろ試行錯誤、四苦八苦、七転八倒 していて、とりあえず過去に作成した WSH を Win7(64bit) で動かしてみたんだけど...
[Win7:64bit] cscript sampleDAO.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

sampleDAO.vbs(1, 1) WScript.CreateObject: "DAO.DBEngine.36" というオブジェクトを作成できませんでした。

[Win7:64bit] cscript sampleADO.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

sampleADO.vbs(3, 1) ADODB.Connection: プロバイダーが見つかりません。正しくインストールされていない可能性があります。

あれ...おかしいなぁ...ちなみに Win7 の WinXP mode では動くことを確 認しているので、動かないわけないんだけど...ちょっと脱線して調べてみた ところ、どうから 64bit から 32bit DLL を呼び出しているのが原因らしいの で、32bit cscript.exe で実行してやればいいらしい。これくらいのことなら cscript.exe でうまくやってくれればいいのに...

[Win7:64bit] %SystemRoot%\SysWOW64\cscript sampleDAO.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

1970/03/14
1979/03/20
1983/05/27
1970/11/28
1974/11/14
1979/03/27

[Win7:64bit] %SystemRoot%\SysWOW64\cscript sampleADO.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

1970/03/14
1979/03/20
1983/05/27
1970/11/28
1974/11/14
1979/03/27

(追記)正しいかどうかはよくわからないけど、備忘録として。WSH ( VBScript ) からは .NET Framework は利用できない、つまりは ADO.NET も利 用できないらしい。が、.NET Framework の中でも利用できるものもあって、 レジストリ HKEY_CLASSES_ROOT で System で始まるものは利用できるらしい。 で、Win7 で調べてみたけれど DB 関係はなさそうな気が...
(追記) ADO の場合で Provider を Microsoft.Jet.OLEDB.4.0 から Microsoft.ACE.OLEDB.12.0 に変更したら、 Win7(64bit) + Access2010(64bit) においてはすんなり動作するようになった 。あと、Microsoft.Jet.OLEDB.4.0 では対応していなかった Access2007 形式 の DB ファイル ( .accdb ) についても、Microsoft.ACE.OLEDB.12.0 では読 めるようだ。ちなみに Access2010/2007 が install されていなければ、 Microsoft Access 2010 Runtime Access 2007 Runtime を install すれば(多分)良いと思われる。(2011/01/31)
変更箇所
oCNN.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\home\test.mdb;"
実行結果(Win7+Access2010)
[D:\home] cscript sampleADO.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

1970/03/14
1979/03/20
1983/05/27
1970/11/28
1974/11/14
1979/03/27

[D:\home] 

実行結果(WinXP SP3)
[C:\home] cscript sampleADO.vbs
Microsoft (R) Windows Script Host Version 5.7
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

C:\home\sampleADO.vbs(3, 1) ADODB.Connection: プロバイダが見つかりません。正しくインストールされていない可能性があります。


[C:\home]

変更箇所
oCNN.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\home\test.accdb;"
実行結果
[D:\home] %systemroot%\syswow64\cscript sampleADO.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

D:\home\sampleADO.vbs(3, 1) Microsoft JET Database Engine: データベースの形式 'D:\home\test.accdb' を認識できません。


[D:\home] 

変更箇所
oCNN.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\home\test.accdb;"
実行結果
[D:\home] cscript sample.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

1970/03/14
1979/03/20
1983/05/27
1970/11/28
1974/11/14
1979/03/27

[D:\home] 
(更に追記) Microsoft.ACE.OLEDB.12.0 につい て、つまりは Win7:64bit に Access2010:64bit を install した環境だから うまくいった(64bit 版 cscript でエラーにならなかった)と。もしも Win7:64bit に Access2010:32bit を install した環境だと、多分うまくいか ない(64bit 版 cscript でエラーになる)んだろうなぁ。

2010/12/21 (Tue)
VLC media player が今年もクリスマスモードなので(実際には何の関係も ありません)、先のプログラムをちと改変。受信だけではなく送信もというわけ で、以前に手動でやっていたことを実行す るプログラムに変更。
サンプルプログラムNo.n02(の変更部分のみ)
31:    i = getaddrinfo( argv[1], "http", &hints, &result );

52:     strcpy( buf, "HEAD / HTTP/1.0\n\n" );
53:     i = send( sock, buf, strlen( buf ), 0 );
54:     if( i == SOCKET_ERROR ){
55:         printf( "send failed: %d\n", WSAGetLastError() );
56:         closesocket( sock );
57:         freeaddrinfo( result );
58:         WSACleanup();
59:         return 1;
60:     }
コンパイル結果および実行結果
[D:\home] cl sampleN02.cpp
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

sampleN02.cpp
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:sampleN02.exe
sampleN02.obj

[D:\home] sampleN02.exe www.u-tokyo.ac.jp
HTTP/1.1 302 Found
Date: Tue, 21 Dec 2010 11:11:05 GMT
Server: Apache/2.0.63 (Unix) mod_ssl/2.0.63 OpenSSL/0.9.8b PHP/5.2.8
X-Powered-By: PHP/5.2.8
Location: http://www.u-tokyo.ac.jp/index_j.html
Connection: close
Content-Type: text/html


[D:\home] 

プログラムは、こちらから文字列「HEAD / HTTP/1.0」と改行コード2個を send 関数を使って送信、相手からの回答を recv 関数を使って受け取り、表 示するというもの。送る改行コードが \n でいいのかよく調べてないけど、実 行してみた結果ではちゃんと動いているようなので、とりあえず今回は良し( 棚上げ)とする。だけどちょっと調べてみたところ、HTTP の改行コードは「CR LF」らしいので \r\n のほうがいいかもしれない...

2010/12/20 (Mon)
先に作成したサンプルプログラムNo.7の解説も書い ていないのに、諸事情につき先走って Windows ネットワークプログラミング。 時間がなくいろいろ調べている暇がなかったので、多少の間違い(勘違い)に ついてはサンプルプログラムということでお許しいただきたい。ちなみに もっと前に作成したネットワークプログラミ ングの Windows 版という感じ。解説については、時間をみつけてそのうち。
サンプルプログラムNo.n01
 1: #pragma comment( lib, "Ws2_32.lib" )
 2: #include <winsock2.h>
 3: #include <ws2tcpip.h>
 4: #include <stdio.h>
 5: 
 6: #define BUFMAX  20
 7: 
 8: int main( int argc, char *argv[] )
 9: {
10:     char buf[BUFMAX+1];
11:     int  i;
12:
13:     if( argc != 2 ){
14:         printf( "Usage: %s [hostname]\n", argv[0] );
15:         return 1;
16:     }
17:     WSADATA wsa;	// Winsock DLL ( Ws2_32.dll ) の初期化
18:     i = WSAStartup( MAKEWORD( 2, 2 ), &wsa );
19:     if( i != 0 ){
20:         printf( "WSAStartup failed: %d\n", i );
21:         return 1;
22:     }
23:     struct addrinfo     hints;
24:     struct addrinfo     *result;
25:     ZeroMemory( &hints, sizeof( hints ) );
26:     hints.ai_family = AF_INET;  // The Internet Protocol version 4 (IPv4) address family.
27:     hints.ai_socktype = SOCK_STREAM;
28:     hints.ai_protocol = IPPROTO_TCP;
29:     // gethostbyname関数ではなく getaddrinfo関数を使用
30:     i = getaddrinfo( argv[1], "daytime", &hints, &result );
31:     if( i != 0 ){
32:         printf( "getaddrinfo failed: %d\n", i );
33:         WSACleanup();
34:         return 1;
35:     }
36:     SOCKET sock;
37:     sock = socket( result->ai_family, result->ai_socktype, result->ai_protocol );
38:     if( sock == INVALID_SOCKET ){
39:         printf( "socket failed: %d\n", WSAGetLastError() );
40:         freeaddrinfo( result );
41:         WSACleanup();
42:         return 1;
43:     }
44:     i = connect( sock, result->ai_addr, result->ai_addrlen );
45:     if( i == SOCKET_ERROR ){
46:         printf( "connet failed: %d\n", WSAGetLastError() );
47:         closesocket( sock ); 
48:         freeaddrinfo( result );
49:         WSACleanup();
50:         return 1;
51:     }
52:     while( ( i = recv( sock, buf, BUFMAX, 0 ) ) > 0 ){
53:         buf[i] = '\0';
54:         fputs( buf, stdout );
55:     }
56:     closesocket( sock );    // ソケットの終了処理
57:     freeaddrinfo( result ); // getaddrinfo 関数で取得したメモリ領域を開放
58:     WSACleanup();           // Winsock DLL ( Ws2_32.dll ) の終了処理
59:     return 0;
60: }
(追記)以下、コンパイル結果および実行結果。
[D:\home] cl sampleN01.cpp
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

sampleN01.cpp
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:sampleN01.exe
sampleN01.obj

[D:\home] sampleN01.exe
Usage: sampleN01.exe [hostname]

[D:\home] sampleN01.exe localhost
connet failed: 10061

[D:\home]

connect 関数のエラー 10061 は「Connection refused」という意味。原因 は多分 Win7 で daytime サービスが動いていないから。プログラムの動作確認 のため一時的に daytime サービスを起動。まず [スタート] → [コントロール パネル] → [プログラム] → [Windows の機能の有効化または無効化] → [簡易 TCP/IP サービス(echo、daytimeなど)] にチェックをつけ、[OK] をクリ ック。続いて [スタート] → [コントロール パネル] → [システムとセキュリティ] → [管理ツール] → [サービス] → [Simple TCP/IP Services]で、スタート アップの種類を [手動] として [適用]、そして[開始]をクリック。

[D:\home] sampleN01.exe localhost
16:40:22 2010/12/20

[D:\home]
2010/12/19 (Sun)
ふとした思い付きを実験するため、Windows 7 Ultimate で telnet コマ ンドを実行してみたところ...
[D:\home] telnet 127.0.0.1
'telnet' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

[D:\home] 

ええっ?そんな馬鹿な。なんで telnet コマンドが使えないんだ?ちょっと 調べてみたところ、[スタート] → [コントロール パネル] → [プログラム] → [Windows の機能の有効化または無効化] → [Telnet クライアント] にチェッ クをつけ、[OK] をクリックで telnet コマンドが使えるようになりました。ま あ default で Telnet サーバーが無効になっているのはいいけど、クライアン トまで無効にしなくても...

[D:\home] telnet 127.0.0.1
接続中: 127.0.0.1...ホストへ接続できませんでした。 ポート番号 23: 接続に失敗しました

[D:\home] 
2010/12/04 (Sun)
最近ぐっと値段が下がり購入しやすくなった感が否めない SSD を、物は試しと購入してみた。今回購入したのは Intel X25-V SATA SSD 40G ( SSDSA2MP040G2K5 )。早速 PC に組み込み、Win7(64bit) を 再 install して、お約束の Windows エクスペリエンス インデックス。
コンポーネント 評価についての詳細 サブスコア
プロセッサ1秒あたりの計算 7.3
メモリ (RAM)1秒あたりのメモリ操作 7.3
グラフィックスWindows Aeroのデスクトップ パフォーマンス 5.2
ゲーム用グラフィックス3Dビジネスおよびゲーム グラフィックス パフォーマンス 6.1
プライマリ ハード ディスクディスクのデータ転送速度 7.2

体感としてスピードアップした!というのをまったく感じないのだが、上 記の結果を見る限り、速くはなっている(→ 以前の結果)ようなので、まあ速いんだろうなぁ。ただ容量が 40G とい うのはやはり若干狭いような気がする。とりあえず C ドライブの「ユーザー」 ディレクトリを D ドライブに移して、しばらく様子を見よう。さて、間違っ て領域開放してしまった 2TB HDD をどうやって復旧させようか...(泣)

2010/09/28 (Tue)
夏休み消化中であまり暇だったので久々にクレジットカードの支払いを調 べてみてびっくり。毎月毎月毎月毎月毎月何をそんなに買ったんだっけ。ああ、 車に始まり、CPUにWin7にOfficeにVisioにCDにDVDにブルーレイにゲームに... なんだ、クレカの不正利用じゃないのか、よかった。って、全然よくないわい! しばらくは緊縮財政で「もやし」を主食に頑張ります。あと、うろうろと出歩 かず、家でおとなしくしています。

2010/09/26 (Sun)
ちょっと留守している間に iPod touch 4G が届いていた。これが初めて の iPod なため、いまいち使い方等がよくわからない。本屋に行っても iPhone 関係の本はあるけど、iPod touch 関係の本は見つからないんだよなぁ。さす が poor man's iPhone。というわけで、ネットでいろいろ調べながら遊んでい るところ。まずは iPod touch 4G と 3G の主な仕様の比較でも。
4G3G
3.5インチ(対角)ワイドスクリーン 3.5インチ(対角)ワイドスクリーン
960x640ピクセル解像度、326ppi 480x320ピクセル解像度、163ppi
Wi-Fi (IEEE 802.11b/g/n(802.11nは2.4GHzのみ)) Wi-Fi (IEEE 802.11b/g)
Bluetooth 2.1 + EDR Bluetooth 2.1 + EDR
111mm*58.9mm*7.2mm 110mm*61.8mm*8.5mm
101g115g
カメラ内蔵(2個)なし
マイク内蔵なし

ちなみに iPod touch に音楽や動画をコピーするためには iTunes という 専用ソフトが必要となります(絶対に必要というわけではないようだけど)。 というか、購入直後の起動時には、PC とつないでiTunes を立ち上げ、iPod touch を認証(もどき?)してやる必要があるようです。まあ、iPod touch を 購入する前から iTunes は MP3 エンコーダとして使用していたので(Gracenote CDDB から各種情報を自動的に get してきてくれて便利なので乗り換えまし た)それは別にどうでもいいのですが、USB hub 経由の接続だとうまくいきま せん(iTunes で認識、無視を繰り返す)でした。どうやら充電できる環境にな いとだめみたいで、PC に直差して、無事認証終了。次回、音楽を聴く/動画 を見る編をお楽しみに!(絶対次回はないと思う...)

(追記) 言葉足らずだったようで。今回使用した USB Hub はコンセント 数の関係で電源供給できない状態(ACアダプタを差していない状態)だったの で駄目だったと思われます。つまり、電源供給可能な USB Hub であれば問題 なかったのではないかと。USB Hub 接続がすべて駄目だというわけではありま せん、ということです。
(追記) 書くのを忘れていたのですが、認証には Apple のアカウント が必要になります。今回の iPod touch は Apple Store で購入したため、ア カウントは作ってあったのですが、秘密の質問やら誕生日やらの情報を追加入 力しなければ駄目でした。あと iTunes で無料アプリをダウンロードする際に も結局アカウントが必要なので、ちゃんとアカウント情報は覚えておきましょう。

2010/09/20 (Mon)
ある夜、勝手に一人盛り上がり、野球を見に行こうと思い立つ。で、一人 で見に行くのもさみしいので、友人二人を誘ってみた。そして教訓。 野球観戦 [ JPG file, 333KB ] はナイト ゲームか、デーゲーム+ドーム球場に限る。いくら涼しくなってきたからとい っても、デーゲーム+非ドーム球場は日光が厳しすぎる。それも大敗となれば なおさらである。次回からよく考えよう。翌日は何故か 競馬場 [ JPG file, 229KB ] へ。相変わ らず馬券を外しまくり、起死回生を狙って最後の最後にどかんと賭けたがそれ も外して大赤字。こっちもよく考えたほうがよさそうだ。何はともあれ二日間 お付き合いいただいた友人二人に感謝しつつ、廃掃法 (廃棄物の 処理及び清掃に関する法律)の本を読みながら帰ってきました。

2010/09/11 (Sat)
いろんなことに腹を立てる毎日を過ごしているせいか、やたら腹が減る。 となると当然やたら飯を食う。でも腹が立つことがごろごろ身近なところに 転がっているので、そのせいですぐに腹が減り、またやたらめったら飯を食う 。うーむ...やはり今いる環境から離脱するのが唯一の解決策か。

さて、Windows プログラミングメモを始め、ウィンドウ1枚も開かないうち に尻切れトンボで終わるのもいかがなものかと思い、とりあえずウィンドウを開 くサンプルプログラムをなんとか作ってみた( 実行結果 [ PNG file, 61KB ]、ちなみに終了させるときには右上のバツを クリック)プログラム作成だけで力尽きたので、解説等については次回以降で... あと、おかしなところがあるかもしれませんが、それは初心者だということで許 してください。

サンプルプログラム No.7
 1: #pragma  comment( lib, "user32.lib" )
 2: #define  UNICODE
 3: #define  _UNICODE
 4: #include <windows.h>
 5: LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
 6: 
 7: int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
 8:                      LPTSTR lpCmdLine, int nCmdShow )
 9: {
10:    wchar_t    szWindowClass[] = L"sample007";
11:    WNDCLASSEX wcex;
12:    
13:    wcex.cbSize        = sizeof( WNDCLASSEX );
14:    wcex.style         = CS_HREDRAW | CS_VREDRAW;
15:    wcex.lpfnWndProc   = WndProc;
16:    wcex.cbClsExtra    = 0;
17:    wcex.cbWndExtra    = 0;
18:    wcex.hInstance     = hInstance;
19:    wcex.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE( IDI_APPLICATION ));
20:    wcex.hCursor       = LoadCursor( NULL, IDC_ARROW );
21:    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
22:    wcex.lpszMenuName  = NULL;
23:    wcex.lpszClassName = szWindowClass;
24:    wcex.hIconSm       = LoadIcon(wcex.hInstance, MAKEINTRESOURCE( IDI_APPLICATION ));
25:    
26:    if( RegisterClassEx( &wcex ) == 0 ){
27:        MessageBox( NULL, L"RegisterClassEx 関数にてエラー発生", L"エラー", MB_OK );
28:        return 1;
29:    }
30:    
31:    HWND hWnd;
32:    hWnd = CreateWindow( szWindowClass, L"ウィンドウタイトル", WS_OVERLAPPEDWINDOW,
33:                         CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL );
34:    if( hWnd == NULL ){
35:        MessageBox( NULL, L"CreateWindow 関数にてエラー発生", L"エラー", MB_OK );
36:        return 1;
37:    }
38:    ShowWindow( hWnd, nCmdShow );
39:    UpdateWindow( hWnd );
40:
41:    MSG  msg;
42:    BOOL b;
43:    while( ( b = GetMessage(&msg, NULL, 0, 0 ) ) != 0 ){
44:        if( b == -1 ) break;
45:        TranslateMessage( &msg );
46:        DispatchMessage( &msg );
47:    }
48:    return( (int)msg.wParam );
49: }
50: 
51: LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
52: {
53:    switch( message ){
54:      case WM_DESTROY:
55:        PostQuitMessage( 0 );
56:        break;
57:      default:
58:        return DefWindowProc( hWnd, message, wParam, lParam );
59:    }
60:    return 0;
61: }
コンパイル結果
[C:\src] cl sample007.cpp
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

sample007.cpp
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:sample007.exe
sample007.obj

[C:\src]
(補足)解説をまとめる時間がないので、とりあえず気になったことをち ょこっとだけ。32,33行目の CreateWindow関数について。この関数の第1パラメータは「ウィンドウク ラス名」、第2は「ウィンドウ名」、第3は「ウィンドウスタイル」、第4は 「ウィンドウの横方向の位置」、第5は「ウィンドウの縦方向の位置」、第6 は「ウィンドウの幅」、第7は「ウィンドウの高さ」、第8は「親ウィンドウ またはオーナウィンドウのハンドル」、第9は「メニュハンドルまたは子ウィ ンドウID」、第10は「アプリケーションインスタンスのハンドル」、第11は「 ウィンドウ作成データ」を指定するらしい。MSDN を読むと、第4パラメータで 「CW_USEDEFAULT」を指定すると、第5パラメータは無視されるらしい。また第 6パラメータについても「CW_USEDEFAULT」を指定すると、第7パラメータは無 視されるらしい。(2011/01/13)

2010/08/27 (Fri)
酸素欠乏・硫化水素危険作業主任者の技能講習を受けてきました。3日間 の講習のうち、2日間は座学、1日間は実技なのですが、何故か非常に疲れま した。まあそれでも普段の仕事に比べれば楽なんですが(笑)今回の講習では( 当然のことながら)「酸欠」とか「硫化水素」というキーワードが多く出てき たのですが、雰囲気に呑まれやすい性格なもので、これらのキーワードを繰り 返し聞いているうちに何故か息苦しくなりまして... 講習を受けていて酸欠で 倒れたらどうしようかと思いました。んが、あたりまえですが酸欠で倒れるこ ともなく無事に修了書を頂きました。さー、この3日間で、どれだけ仕事がた まっているかな...

2010/08/26 (Thu)
耳の状態も良くなり、夜は若干涼しくなってきて、時間もあったので、久 々に映画館に。で、借りぐらしのアリエッティを見てきたわけだけれども... 見終わった直後、何の感想もなかった。話が動く前に終わっていたという感じ。 ここまで見終わった後に何も残らない作品は久々だなぁ。たいていは「つまら ん」とか「意味わからん」とか怒りが残るんだけど(笑)ああ、そうか、現代に 足りないのはこれか、これが「ゆとり」というやつか。なるほど。が、それに してもまったくもって腑に落ちない。是非ともこの作品を褒めている人が、ど こをどうやって、どういう観点で、どういう考えで、褒めているのか聞いてみ たいものだ。まあ、そんな映画でした。


Copyright(C) 2010 Hiroaki Fujiuchi ( fujiuchi@gmail.com )
inserted by FC2 system