その他



CRT

Cのランタイムライブラリのことで、Win32APIではないC言語の標準ライブラリなどのことを指す。
多くのCRT関数がセキュリティが強化された新しいバージョンに置き換えられている。
(だいたいが"_s"が関数の後ろについている)


EXTERN_C

WinNT.hにて…
#define  EXTERN_C     extern "C"
と定義されている


IID

Guiddef.hにて…
typedef  GUID     IID;
        ↓↓↓
typedef struct _GUID {
    unsigned long Data1;
    unsigned short Data2;
    unsigned short Data3;
    unsigned char Data4[ 8 ];
} GUID;
…という事で、正体はGUIDでした。


extern "C++"

ぶっちゃけ、extern "C"ではないですよという事。
関数名はC++コンパイラにより変換されて別の名前のシンボル名が生成される。
C++で普通にコンパイルする分にはデフォルトで extern "C++"になっています。


extern "C"

簡単に言えばC++でCの関数を使うための指定子。

C,C++の関数名はオブジェクトファイルの中でシンボルとして扱われる。
Cではシンボル名=関数名と捉えることができるが、
C++ではコンパイラにより関数名に変換が加えられ、関数名とは
異なるシンボル名が生成される(生成方法は処理系に依存)
C++でこんなことをしている理由はオーバーロードや名前空間を
実現するため。

実際、プロジェクトファイルに.cppと.cを混在させ、Cソースの関数を
呼び出すとCの関数のシンボルが未解決というリンクエラーが出てしまう。
これは先に述べた関数名とシンボル名の不一致から発生する。

で、これを回避するために extern "C" を使う。
使い方としては

extern "C" void function();
extern "C" {
   void func1();
   void func2();
}

こんな感じ。
ただし、extern "C" はC++だけで使えるものなので、
Cのコンパイラだと怒られてしまう。よって

#ifdef __cplusplus
extern "C" {
#endif

   void func();
   void func2();

#ifdef __cplusplus
}
#endif

のように一工夫する必要がある。
尚、 __cplusplusはC++でコンパイルするときに定義されるもの。


MIDL_INTERFACE

RpcNdr.hにて…
#define  MIDL_INTERFACE(x)     struct DECLSPEC_UUID(x)  DECLSPEC_NOVTABLE
        ↓↓↓
WinNT.hにて…
#define  DECLSPEC_UUID(x)     __declspec(uuid(x))
#define  DECLSPEC_NOVTABLE     __declspec(novtable)
…と定義されている。

▼関連項目
    ・__declspec()
    ・uuid()
    ・novtable


BEGIN_INTERFACE

ObjBase.hにて…
#if defined(_MPPC_)  && \
    ( (defined(_MSC_VER) || defined(__SC__) || defined(__MWERKS__)) && \
    !defined(NO_NULL_VTABLE_ENTRY) )
   #define BEGIN_INTERFACE virtual void a() {}
   #define END_INTERFACE
#else
   #define BEGIN_INTERFACE
   #define END_INTERFACE
#endif
と定義されているが、現状では _MPPC_が定義されていないので
特に意味を持たない感じである。


STDMETHODCALLTYPE

WinNT.hにて…
#define  STDMETHODIMP         HRESULT  STDMETHODCALLTYPE
        ↓↓↓
#define  STDMETHODCALLTYPE         __stdcall
…と定義されている。


template<class Q>



END_INTERFACE

BEGIN_INTERFACEを参照してね。


__declspec()

マイクロソフト独自の拡張属性構文であり、その中で指定された属性が、続いて宣言されるオブジェクトや関数に適用されます

【msdnの英文を無理矢理和訳】
Microsoft Specific
マイクロソフト指定子(=specifier)

The extended attribute syntax for specifying storage-class information uses the __declspec keyword, which specifies that an instance of a given type is to be stored with a Microsoft-specific storage-class attribute listed below. Examples of other storage-class modifiers include the static and extern keywords. However, these keywords are part of the ANSI specification of the C and C++ languages, and as such are not covered by extended attribute syntax. The extended attribute syntax simplifies and standardizes Microsoft-specific extensions to the C and C++ languages.
ストレージクラスの情報を特定するための拡張属性構文として、__declspecキーワードが使われる(ストレージクラス指定子)。指定子のパラメータとして属性を指定するが、それを以下に列挙する。他のストレージクラス指定子の例としては "static" や "extern" が挙げられる。
しかしながら、これらのキーワードはC、C++のANSI規格の一部であり、拡張属性構文に対応してはいない。拡張属性構文はC、C++言語を拡張するためにマイクロソフト指定子を簡素化、規格化する。

This is the extended attribute grammar for C++:
以下がC++用の拡張属性文法である。

decl-specifier :
        __declspec ( extended-decl-modifier-seq )
extended-decl-modifier-seq :
        extended-decl-modifier opt
        extended-decl-modifier extended-decl-modifier-seq
extended-decl-modifier :
        align(#)
        allocate("segname")
        deprecated
        dllimport
        dllexport
        naked
        noinline
        noreturn
        nothrow
        novtable
        property(get=get_func_name|,put=put_func_name)
        selectany
        thread
        uuid("ComObjectGUID")

White space separates the declaration modifier sequence. Examples appear in later sections.
スペースで区切ってパラメータを記述する。例を以下に挙げる

Extended attribute grammar supports these Microsoft-specific storage-class attributes: align, allocate, deprecated, dllexport, dllimport, naked, noinline, noreturn, nothrow, novtable, selectany, and thread. It also supports these COM-object attributes: property and uuid.
拡張属性文法は次のマイクロソフト指定子ストレージクラス属性をサポートしている:align, allocate, deprecated, dllexport, dllimport, naked, noinline, noreturn, nothrow, novtable, selectany, thread。また、COMオブジェクト用の属性として property, uuidをサポートしている。

The thread, naked, dllimport, dllexport, nothrow, property, selectany, and uuid storage-class attributes are properties only of the declaration of the object or function to which they are applied. The thread attribute affects data and objects only. The naked attribute affects functions only. The dllimport and dllexport attributes affect functions, data, and objects. The property, selectany, and uuid attributes affect COM objects.
thread, naked, dllimport, dllexport, nothrow, property, selectany, uuidストレージクラス属性はオブジェクト、もしくは関数の宣言の際に適用されるが、と単純にプロパティとして作用する。threadはデータ、もしくはオブジェクトにしか使えない。nakedは関数にしか使えない。dllimportdllexportは関数、データ、オブジェクトに使用可能。property, selectany, uuidはCOMオブジェクトに使用する。

The __declspec keywords should be placed at the beginning of a simple declaration. The compiler ignores, without warning, any __declspec keywords placed after * or & and in front of the variable identifier in a declaration.
__declspecキーワードは宣言の頭に記述する。コンパイラは__declspecキーワードが*&の後ろ、変数の前に記述されていると警告はするが無視する。

A __declspec attribute specified in the beginning of a user-defined type declaration applies to the variable of that type. For example:
__declspec属性がユーザー定義タイプの宣言の頭で指定されるとそれが変数に適用される。例えば…

__declspec(dllimport) class X {} varX;

In this case, the attribute applies to varX. A __declspec attribute placed after the class or struct keyword applies to the user-defined type. For example:
この場合、属性は varX に適用される。__declspec属性が class や struct の後に記述されると属性はユーザー定義タイプに適用される。例えば…

class __declspec(dllimport) X {};

In this case, the attribute applies to X.
この場合は属性は X に適用される。

The general guideline for using the __declspec attribute for simple declarations is as follows:
単純な宣言に用いる__declspec属性の一般的な使い方のガイドラインとしては以下のようなものである

decl-specifier-seq  init-declarator-list;

The decl-specifier-seq should contain, among other things, a base type (e.g. int, float, a typedef, or a class name), a storage class (e.g. static, extern), or the __declspec extension. The init-declarator-list should contain, among other things, the pointer part of declarations. For example:
decl-specifier-seqパートはベースタイプ(int, flot, typedef, class名など)、ストレージクラス(static や extern)、__declspec拡張など(その他にもあるが)を含む。init-declarator-listパートはポインタ部分の記述を含む。例としては…

__declspec(selectany) int * pi1 = 0; //OK, selectany & int both part of decl-specifier
int __declspec(selectany) * pi2 = 0; //OK, selectany & int both part of decl-specifier
int * __declspec(selectany) pi3 = 0; //ERROR, selectany is not part of a declarator

The following code declares an integer thread local variable and initializes it with a value:
次のコードはスレッドタイプのint型ローカル変数の宣言と値の初期化である。

__declspec( thread ) int tls_i = 1;


uuid()

インターフェイスまたはクラスの定義でC++属性のuuid(汎用一意識別子)の指定を行う際に使う。
パラメータに指定するのは 128bitの一意の識別子。

uuid を指定しない場合は、コンピュータ上にある異なる属性のプロジェクトの同名のインターフェイスやクラスに対して、1 つの GUID がコンパイラによって生成される。

Uuidgen.exe または Guidgen.exe を使用すると、独自の ID を生成できる。
これらのツールのいずれかを実行するには、[スタート] をクリックし、メニューの [ファイル名を指定して実行] をクリック、次に、必要なツールの名前を入力する。

ATL も使用しないプロジェクトでは、uuid 属性の指定は uuid の __declspec 修飾子の指定と同じです。クラスの uuid の取得には __uuidof を使用できます。

指定対象は
class、struct、interface、union、enum

MIDL_INTERFACEを介してコールされているが、
例えば IUnknownの場合、
MIDL_INTERFACE("00000000-0000-0000-C000-000000000046")
という形で呼ばれている。
即ち uuid() にも文字列が送られているっぽいのだがそんなもんなのかな?

英文説明では使用例として
struct __declspec(uuid("00000000-0000-0000-c000-000000000046")) IUnknown;
struct __declspec(uuid("{00020400-0000-0000-c000-000000000046}")) IDispatch;
となっており、文字列で渡せとの説明がある。


ちなみに uuid について…
【uuid】
汎用一意識別子(はんよういちいしきべつし、Universally Unique Identifier)
UUIDは、分散システム上でどこかが統制を取らずとも、一意に特定可能な識別子の作成を目的としており、UUIDは重複や偶然の一致が起こりえないと確信して用いることができる。なお、UUIDの実装として最も広く使われているのは、マイクロソフトによるグローバル一意識別子 (GUID)である。

UUIDは16バイトの数値で表され、「550e8400-e29b-41d4-a716-446655440000」のように表現する。理論上、UUIDは25616、およそ3.4の1038通り存在することになり、これを使い果たすには、地球の寿命に相当する100億年の間、1ナノ秒おきに1兆個のUUIDを作ってようやく可能になるという計算になる。


novtable

この形式の _declspec は,あらゆるクラス宣言に適用できますが,純粋インターフェースクラス(独自にはインスタンス化されないクラス)のみに適用しなければなりません。_declspec は,クラスのコンストラクタおよびデストラクタで vfptr を初期化するコードをコンパイラが生成するのを防止します。多くの場合で,これはクラスと関連付けられている vtable への参照だけを削除するので,vtable はリンカが削除します。この形式の _declspec を使うと,コードのサイズが大幅に小さくなります。


__uuidof()


__uuidof( expression )

expressionにアタッチされたGUIDを取り出す。
最終更新:2008年10月05日 17:09
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。