MIDL と MkTypLib の違い

Note

Mktyplib.exe ツールは古くなっています。 代わりに MIDL コンパイラを使用してください。

 

MIDL コンパイラが MkTypLib と異なる重要な領域がいくつかあります。 これらの違いのほとんどは、MIDL が MkTypLib よりも C 構文に向いているためです。

一般に、IDL ファイルで MIDL 構文を使用する必要があります。 ただし、既存の ODL ファイルをコンパイルする必要がある場合、または MkTypLib との互換性を維持する必要がある場合は、 /mktyplib203 MIDL コンパイラ オプションを使用して、MIDL を Mkktyplib.exe バージョン 2.03 のように強制的に動作させます。 (これは MkTypLib ツールの最後のリリースです)。具体的には、 /mktyplib203 オプションを使用すると、次の違いが解決されます。

  • 複合データ型の typedef 構文

    MkTypLib では、次の定義の両方で、タイプ ライブラリの "this_struct" のTKIND_RECORDが生成されます。 タグ "struct_tag" は省略可能であり、使用されている場合、タイプ ライブラリには表示されません。

    typedef struct struct_tag { ... } this_struct;
    typedef struct { ... } that_struct;
    

    省略可能なタグがない場合、MIDL はそれを生成し、ユーザーが指定した定義に効果的にタグを追加します。 最初の定義には タグがあるため、MIDL は "this_struct" のTKIND_RECORDと "this_struct" のTKIND_ALIASを生成します ("this_struct" を "struct_tag" のエイリアスとして定義します)。 2 番目の定義にタグがないため、MIDL は、ユーザーにとって意味のない、管理された名前 (MIDL の内部) のTKIND_RECORDを生成し、"that_struct" のTKIND_ALIASを生成します。

    これは、ユーザー インターフェイスにレコードの名前を表示するタイプ ライブラリ ブラウザーにとって潜在的な影響を与える可能性があります。 TKIND_RECORDに実際の名前が必要な場合は、認識できない名前がユーザー インターフェイスに表示される可能性があります。 この動作は 共用体 定義と 列挙型 定義にも適用され、MIDL コンパイラはそれぞれTKIND_UNIONsとTKIND_ENUMsを生成します。

    MIDL では、C スタイルの 構造体共用体列挙型 の定義も許可されます。 たとえば、MIDL では次の定義が有効です。

    struct my_struct { ... };
    typedef struct my_struct your_struct;
    
  • ブール型

    MkTypLib では、 ブール型 の基本型と MkTypLib データ型 BOOL は、VARIANT_BOOLにマップされ、 短い値として定義されているVT_BOOLに相当します。 MIDL では、 ブール型 の基本型は 、符号なし char として定義されるVT_UI1と等価であり、BOOL データ型は long として定義されます。 これにより、同じファイルに IDL 構文と ODL 構文を混在させ、MkTypLib との互換性を維持しようとすると、問題が発生します。 データ型は異なるサイズであるため、マーシャリング コードは型情報で説明されているものと一致しません。 タイプ ライブラリにVT_BOOLが必要な場合は、VARIANT_BOOLデータ型を使用する必要があります。

  • ヘッダー ファイル内の GUID 定義

    MkTypLib では、GUID は、GUID の定義済みまたはインスタンス化された GUID を生成するために条件付きでコンパイルできるマクロを使用してヘッダー ファイルで定義されます。 MIDL は通常、生成されたヘッダー ファイルに GUID の定義済みを配置し、GUID のインスタンス化は /iid スイッチによって生成されたファイル内でのみ行われます。

/mktyplib203 スイッチを使用すると、次の動作の違いを解決できません。

  • 大文字小文字の区別

    MIDL では大文字と小文字が区別され、OLE オートメーションは大文字と小文字は区別されません。

  • 列挙型宣言内のシンボルのスコープ

    MkTypLib では、列挙型のシンボルのスコープはローカルです。 MIDL では、列挙型のシンボルのスコープは、C の場合と同様にグローバルです。たとえば、次のコードは MkTypLib でコンパイルされますが、MIDL で重複する名前エラーが生成されます。

    typedef struct { ... } a;
    enum {a=1, b=2, c=3};
    
  • パブリック属性のスコープ

    インターフェイス ブロックに public 属性を適用すると、MkTypLib はそのインターフェイス ブロック内のすべての typedef をパブリックとして扱います。 MIDL では、パブリックにする typedef に public 属性を明示的に適用する必要があります。

  • Importlib の検索順序

    複数のタイプ ライブラリをインポートし、これらのライブラリに重複する参照が含まれている場合、MkTypLib は、検出された最初の参照を使用してこれを解決します。 MIDL は、最後に見つけた参照を使用します。 たとえば、次の ODL 構文を指定すると、MkTypLib を使用してコンパイルする場合はライブラリ C はライブラリ A の MOO typedef を使用し、MIDL でコンパイルする場合はライブラリ B の MOO typedef を使用します。

    [...]library A
    {
        typedef struct tagMOO
        {...}MOO
    }
    
    [...]library B
    {
        typedef struct tagMOO
        {...} MOO
    }
    
    [...]library C
    {
        importlib (A.TLB)
        importlib (B.TLB)
        typedef struct tagBAA
        {MOO y;}BAA
    }
    

    これに対する適切な回避策は、このような各参照を次のように正しいインポート ライブラリ名で修飾することです。

    typedef struct tagBAA
        {A.MOO y;}BAA
    
  • VOID データ型が認識されない

    MIDL は C 言語 の void データ型を認識し、OLE Automation VOID データ型を認識しません。 VOID を使用する ODL ファイルがある場合は、この定義をファイルの先頭に配置します。

void void ''' を#defineする

  • 指数表記

    MIDL では、指数表記で表される値を引用符で囲む必要があります。 たとえば、"-2.5E+3"

  • LCID 値と定数

    通常、MIDL はファイルの解析時に LCID を考慮しません。 値に対してこの動作を強制する場合、または定数を定義するときにロケール固有の表記を使用する必要がある場合は、値または定数を引用符で囲みます。

詳細については、「 /mktyplib203/iid、および OLE データ型のマーシャリング」を参照してください