次の方法で共有


MIDL と MkTypLib の違い

手記

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 の内部) と "that_struct" のTKIND_ALIASのTKIND_RECORDを生成します。

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

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

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

    MkTypLib では、Boolean 基本型と MkTypLib データ型 BOOL は、VARIANT_BOOLにマップされ、短いとして定義されているVT_BOOLに相当します。 MIDL では、Boolean 基本型は、符号なし文字として定義されるVT_UI1に相当し、BOOL データ型は 長いとして定義されます。 これにより、同じファイルに 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};
    
  • パブリック属性のスコープ

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

  • 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 ファイルがある場合は、ファイルの先頭に次の定義を配置します。

#define VOID void '''

  • 指数表記

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

  • LCID 値と定数

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

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