![]() |
zunbe |
![]() |
|
| [ 1 2 ] [次へ>] [最後>>] | ||
2008/08/13
|
今月は、久しぶりにVC++で開発の仕事をしている。
最近は perl や VB での開発が多かったのだが、今回は、そこそこクリティカルな処理を書く必要があるので、久しぶりに VC++ を開発言語に選択してみた。
VC++での開発は何年ぶりだろうか。
久しぶりに VC++ を使ってみたけれど、やはり、VB にくらべるとプロ志向の開発言語だな。
当たり前だが、VB に比べて、細かいコントロールが自由にできる。
ライブラリは、いろいろ理由があって、最新の .NET Framework でもなく、ATL でもなく、MFC を選択した。
MFC は、さすがに古さは感じるが、名前の通りの基本的なクラス・ライブラリで、Win32 API をラップしただけのものであるので、扱いやすいし、開発関連情報もふんだんにあるので開発しやすい。
ただ、最近の開発で使うことが多くなった、正規表現や文字列の簡単操作ライブラリ(Split や Join)などがないので、このあたりの簡単操作関数をいちいち手作りが必要があり、ちとめんどくさいなぁ、と感じる事もある。
まぁ、でも、久しぶりの VC++ 開発を堪能している ずんべ であります。(^^)
このエピソードはいかがでしたか? ![]() ![]() | ![]() |
投稿者 zunbe : 2008/08/13 01:00:28 | コメント (0) | トラックバック (0)
2008/02/14
|
久しぶりにプログラミングねた。
Microsoft Internet Explorer上で動作させるActiveXコントロールを作成したのだが、ActiveXのインストールに失敗する場合があるという症状が発生した。
おかしい、理屈の上では失敗する要因が見当たらない。
何かダウンロード時の実行ログを入手する方法はないか。
ググってみる。
あった。
KB252937 コード ダウンロードが失敗する理由については、詳細を検索する方法。
記載されている方法でダウンロード時のログを確認してみると、確かに自動インストールしようとしているコンポーネントのダウンロードかインストールで失敗している。
インストール中に何らかの原因で失敗している事はわかったが、その肝心の原因がさっぱりわからない。
何度かActiveXのインストールをトライしてみる。
すると、インストールを実行する度に、失敗するコンポーネントが変わる。
最初は TabCtl32.cab で失敗、次は MSComCtl.cab で失敗…。
う~ん、どういう事だ?
更にググってみる。
更にググってみる…。
更にググってみる……。
情報が見つからない。
う~ん? なんでだ? なんで失敗するんだ?
ふと、ブラウザでマイクロソフトのサイトに置かれているコンポーネントにアクセスしてみた。
http://activex.microsoft.com/controls/vb6/TabCtl32.cab
http://activex.microsoft.com/controls/vb6/MSComCtl.cab
http://activex.microsoft.com/controls/vb6/MSMask32.cab
あれ? 404 Not Found になったぞ。
リロードしてみる。
あれ? 今度はダウンロードのダイアログが表示されたぞ。
なんだこりゃ。
Linux マシンに移り、wget でダウンロードをトライしてみる。
$ wget http://activex.microsoft.com/controls/vb6/TabCtl32.cab --23:01:25-- http://activex.microsoft.com/controls/vb6/TabCtl32.cab => `TabCtl32.cab' Resolving activex.microsoft.com... done. Connecting to activex.microsoft.com[207.46.249.55]:80... connected. HTTP request sent, awaiting response... 404 Not Found 23:01:25 ERROR 404: Not Found. $ wget http://activex.microsoft.com/controls/vb6/TabCtl32.cab 100%[==============================================>] 115,971 135.15K/s ETA 00:00 23:01:29 (135.15 KB/s) - `TabCtl32.cab' saved [115971/115971] $ wget http://activex.microsoft.com/controls/vb6/TabCtl32.cab |
やはり、成功するときと失敗するときがある。
なんだこりゃ?
ダウンロードに失敗する理由はわからないが、間違いなくこれが原因だ。
ダウンロードするコンポーネントをすべてローカルサーバに置き、デストリビューション・ウィザードでコンポーネントを代替サーバからダウンロードするように設定してActiveXコンポーネントを作り直してみる。
インストールを試してみると…成功!
どういうこっちゃい。
マイクロソフト君、activex.microsoft.com の挙動、おかしくないかい?
このエピソードはいかがでしたか? ![]() ![]() | ![]() |
投稿者 zunbe : 2008/02/14 13:35:13 | コメント (4) | トラックバック (1)
2005/12/08
|
初心者にありがちな誤ったプログラム例をひとつ。
Visual Basic で書かれているプログラムで、以下の様なコードを最近、よく目にする。
--
Call MsgBox("プロンプト", vbCritical + vbOKOnly, "タイトル")
--
このコードには、根本的な間違いがある。
この部分である。
vbCritical + vbOKOnly
「vbCritical」と「vbOKOnly」に、値がどのように定義されていて、どのような結果を求める必要があるかを考えれば、「+」で演算を行ってはならない事は明白である。
ここで行おうとしている演算は、「vbCritical」と「vbOKOnly」が持つ値のビットパターンを演算し、立っているビットをすべて残す事が目的なのであるから、行うべき演算は「+」ではない。
当然、この様に記述するべきである。
vbCritical Or vbOKOnly
よほど変な組み合わせを書かなければ、「+」で記述しても誤動作する事は無い。
しかし、そんな事は問題ではない。
関数や処理が求めている演算方法を正しく理解し、適切な演算子を使用することは、プログラマとして当たり前にできなければならない事だと思う。
しかし、最近は、「動くからいいじゃん」的な考えのプログラマが多いような気がしてならない。
若いプログラマは、もっともっと勉強してほしいと思う。
このエピソードはいかがでしたか? ![]() ![]() | ![]() |
投稿者 zunbe : 2005/12/08 03:18:02 | コメント (0) | トラックバック (0)
2005/09/24
|
学校などでC言語を習うと、たいていこんな風に教わる。
・コンパイル時に出る警告は無視していい。
これは、とんでもない話である。
たとえば、以下の様なプログラム。
--
#include <stdio.h>
#include <io.h>
void main(void);
void main(void)
{
FILE *fp;
fp = fopen("hoge.txt", "r");
:
close(fp);
}
--
このプログラムは、バグがある。
本来、fclose() を呼び出すべきところで close() を呼び出している。
VC++ で、/W 系の警告オプションを指定して、このプログラムをコンパイルすると以下の警告が出力される。
・close() の第1引数が実引数と仮引数で異なっている。
このソースのままコンパイル、リンクしても、もちろん、正常に動作しない。
アクセス例外を引き起こす可能性もある。
無視してはならない警告である。
ソフトウェアを開発する場合、可能な限り厳しい警告オプションを設定し、可能であれば警告をエラーとみなすオプションを設定するべきである。
VC++なら、以下のオプションだ。
/W4 /WX
/W4 は警告レベル最大のオプション、/WX は警告をエラーとみなすオプションである。
初心者にこういう話をすると、必ず眉をひそめてこう言う。
「警告は無視していいのではないですか?」
たしかに、学校ではそう教わったかもしれない。
しかしそれは、学校の授業で「とりあえず、無視していい」というだけの話であって、実務では許されない。
警告を無視してコンパイルすれば、後で自分が泣きを見る事になる。
動いているように見せかけて、実はシステムを破壊しながら動作するわけだから、動作中にクラッシュしたとしても、原因究明に余計な時間を費やす事になる。
そもそも、警告を無視しようとする発想がわからない。
コンパイラが、「それ間違ってるんじゃないの?」と、障害が発生する可能性を指摘してこれているのである。
上記の様なミスは、目で追って見つけられるものではない。
コンパイラがミスを見つけてくれるのである。
これを無視するなんて、とんでもない話だ。
警告は、原則としてエラーであると考えて、すべて排除すべきである。
ちなみに、この説明をして、「警告を排除しろ」と指示すると、たいていの初心者は以下の様にプログラムを修正する。
--
close((int)fp);
--
困ったものである。
![]() Microsoft Visual Studio .NET Professional Version 2003 |
このエピソードはいかがでしたか? ![]() ![]() | ![]() |
投稿者 zunbe : 2005/09/24 08:49:11 | コメント (0) | トラックバック (0)
2005/07/17
|
C言語の初心者に多い間違いに、NULLと空文字列の混同がある。
たとえば、こんなコードがある(最近はこんな関数、めっきり使わなくなったけど)。
-----
char drive[_MAX_PATH];
char path[_MAX_PATH];
char fname[_MAX_PATH];
char ename[_MAX_PATH];
_splitpath("C:\HOGE.txt",drive,path,fname, ename):
-----
_splitpathという関数は、取得する drive、path、fname、ename のうち、取得する必要の無いパラメータには、NULLを渡す事ができる。
ファイル名と拡張子だけが欲しい場合、以下の様に記述する。
-----
char fname[_MAX_PATH];
char ename[_MAX_PATH];
_splitpath("C:\HOGE.txt",NULL,NULL,fname, ename):
-----
これを、初心者は以下の様に記述してしまう。
-----
char fname[_MAX_PATH];
char ename[_MAX_PATH];
_splitpath("C:\HOGE.txt","","",fname, ename):
-----
これは明らかに間違いである。
_splitpath に、メモリ領域のポインタが渡ってしまうので、_splitpath は、ドライブ名とパスを引数で渡されたポインタに入れようとし、結果、メモリ領域内が破壊される。
このコードを書いた初心者に「その引数には、NULLを渡さないとダメだよ」と教えても、「だから、ヌルを渡してるじゃないですか」とのたまう。
確かにわかりにくい概念ではあるとは思うが、「ポインタに何が入っているか」を考えれば、_splitpathに「""」を渡したら、関数側の処理で判断できない事くらいわかりそうなもんだ。
このエピソードはいかがでしたか? ![]() ![]() | ![]() |
投稿者 zunbe : 2005/07/17 01:06:35 | コメント (0)
| [ 1 2 ] [次へ>] [最後>>] | ||