< March 2004 | April 2004 | May 2004 >

April 30, 2004

static

VB 使いが C++ で違和感を感じるもののひとつが static かも知れないな。たとえば関数スコープの変数を、static/Staticで加算していくこんなクラス

' VB
' CIncriment
Option Explicit

Public Function Incriment() As Long
Static slngNumber       As Long
    
    slngNumber = slngNumber + 1
    Incriment = slngNumber
End Function
// C++
// CIncriment
class CIncriment {
public:
	int Incriment ()
	{
		static int siNumber = 0;
		return ++siNumber;
	}
};

これで、だいたい一緒かな?これを、インスタンスを作成しては、Incriment メソッドをコールしてみる。
まず VB 。フォームモジュールにコマンドボタンを一個。

続きを読む...

April 28, 2004

atoin 関数

atoi 関数のレングス指定あり版です。なんてことはないですが、しょっちゅう作るのも面倒かと思って。

続きを読む...

April 27, 2004

メンバへのポインタ演算子 ってやつ

メンバへのポインタ演算子ってやつがある。MSDNライブラリでの説明はこう。

メンバへのポインタ演算子: .* および ->*
pm-expression :
cast-expression
pm-expression .* cast-expression
pm-expression ->* cast-expression
二項演算子 .* は第 1 オペランドを第 2 オペランドに結合します。第 1 オペランドはクラス型のオブジェクトとし、第 2 オペランドはメンバへのポインタ型とする必要があります。
二項演算子 ->* も第 1 オペランドを第 2 オペランドに結合します。この第 1 オペランドはクラス型のオブジェクトを指すポインタ、第 2 オペランドはメンバへのポインタ型にする必要があります。
演算子 .* を使った式の第 1 オペランドの型は、第 2 オペランドで指定した、メンバへのポインタと同じクラス型にするか、そのクラスから明確に継承させたあいまいさのない型にする必要があります。
演算子 ->* を使った式の第 1 オペランドの型は、第 2 オペランドで指定した型の "クラス型へのポインタ" にするか、そのクラスから明確に継承させたあいまいさのない型にする必要があります。

この説明で、は、はーん、ってわかった人いますかね。私はわかりませんでした。

この演算子が何なのか、何でこんなものいるか、というと、まず、クラスのメンバ関数を、関数ポインタからコールしたい、という場合があるとします。クラスのメンバ関数も関数なので、もちろん関数ポインタをとることができます。たとえばこんな感じ。

続きを読む...

April 15, 2004

Oracle のコメント

Oracle の表と列にコメントをつけることができます

SQL> comment on table MY_TABLE is '私のテーブル';

コメントが作成されました。

SQL> comment on column MY_TABLE.MY_COLUMN is '私のカラム';

コメントが作成されました。

こうして付けたコメントは USER_TAB_COMMENTS と USER_COL_COMMENTS というデータディクショナリで参照することができます。こんな感じのテーブルになってます。

SQL> desc USER_TAB_COMMENTS
 名前                                      NULL?    型
 ----------------------------------------- -------- ----------------------------
 TABLE_NAME                                NOT NULL VARCHAR2(30)
 TABLE_TYPE                                         VARCHAR2(11)
 COMMENTS                                           VARCHAR2(4000)

SQL> desc USER_COL_COMMENTS
 名前                                      NULL?    型
 ----------------------------------------- -------- ----------------------------
 TABLE_NAME                                NOT NULL VARCHAR2(30)
 COLUMN_NAME                               NOT NULL VARCHAR2(30)
 COMMENTS                                           VARCHAR2(4000)

NetServerGetInfo で ローカルコンピュータ名を取得する

仕事で、ローカルコンピュータ名を取得する必要がありそうなのですが、WinSock で取得しても面白くないので、今回は NetServerGetInfo で、VB 用の関数を作ってみました。ただし、Windows Me、98、95 等では関数定義が異なるため、使用できません。

続きを読む...

April 9, 2004

Dll 側で、自モジュールのパスを取得する

DLLよりコールした GetModuleFileName で取得されるパスにもコメントをいただいたのですが、DLL 内で GetModuleFileName を、1つ目の引数 hModuleNULL を指定して呼び出すと、その DLL をロードしたプロセスの実行ファイルのパスが取得されてしまいます。ほんで結局、DLL 側で、自分自身のパスを知る方法はないの?って話です。

コメントをいただいたときは、「MFC の DLL なら、theApp.m_pszHelpFilePath の拡張子を"exe"に替えれば・・・」と、とぼけた答えを返してしまったのですが、ふと思いついて、DllMain の宣言を見ると、引数に HANDLE hModuleというのがあるではありませんか。それを渡して GetModuleFileName してみました。

BOOL APIENTRY DllMain (HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    TCHAR   szModuleFileName [_MAX_PATH] = _T ("");
    GetModuleFileName ((HMODULE) hModule, szModuleFileName, _MAX_PATH);
    MessageBox (NULL, szModuleFileName, _T ("ModuleFileName"), MB_OK);
    return TRUE;
}

結果はきちんと、DLL 自身のパスが表示されました。あとで、MSDN ライブラリの DllMain をみると、ちゃんと書いてありました。

DLL モジュールのハンドルを指定します。この値は、DLL のベースアドレスです。DLL の HINSTANCE は、DLL の HMODULE と同じことを意味します。(これらは混同されていることがあります。詳細については Knowledge Base の Q81496 の「Dealing with hModule and hInstance」を参照してください。MSDN ライブラリの[検索]タブでも Q81496 を参照できます。)。したがって、モジュールハンドルを必要とする GetModuleFileName 関数などを呼び出す際に、hinstDLL パラメータで指定した値を使うことができます。

ちゃんと読めよ、ということかしら・・・

April 1, 2004

伝統形式 の 関数宣言

今日、こんな古いソースの中にこんな関数定義を見かけました。

int func (foo, bar)
unsigned char *foo, *bar;
{
    /* 処理・・・ */
    ・・・

注目すべきは引数の宣言部分なのですが、調べてみると「伝統形式」と呼ばれるものらしいです。

ANSI C標準以前の宣言方法を伝統形式や旧方式というように呼ばれています
この方式による宣言は現代のコンパイラでも可能です
さらに、過去のC言語のソースで伝統形式が使われているものを見かけることがあるかもしれません
ここで、伝統形式の仮引数宣言を覚えておきましょう
(中略)
大きく違うのは、引数リストで仮引数となる変数名しか宣言しないということです
その後、コードブロックに入る前にそれぞれの仮引数に型を宣言するという形になっています