Visual C++で#importを使いタイプライブラリを使用しようとしたところビルドエラーが出たのでその解決方法を紹介。なお、今回はATL/C++でAddinを作る場合を例にしている。
名前の重複エラー
通常#importを書く場合、stdafx.hあたりに書いていくことと思うのだが、今回はアドインを作成にあたり次のような文字列を追加した。
1 2 3 4 5 6 7 |
// Office #import "libid:2DF8D04C-5BFA-101B-BDE5-00AA0044DE52" version("2.4") lcid("0") \ raw_interfaces_only named_guids // Excel #import "libid:00020813-0000-0000-C000-000000000046" version("1.6") lcid("0") \ raw_interfaces_only named_guids |
これは、最初からstdafx.hに書かれている#import文を参考に書いてみたもの。libidやversionは、OLE/COM Object Viewer(Visual Studio 2005だとC:\Program Files\Microsoft Visual Studio 8\Common7\Tools\Binへんにある)で調べたもの。
GUIDをコピー
さて、実際にこれをビルドしようとするとエラーが表示される。
c:\documents and settings\********\デスクトップ\myaddin1\myaddin1\debug\excel.tlh(7354) : warning C4003: マクロ ‘RGB’ に指定された実引数の数が少なすぎます。
c:\documents and settings\********\デスクトップ\myaddin1\myaddin1\debug\excel.tlh(7354) : error C2059: 構文エラー : ‘(‘
c:\documents and settings\********\デスクトップ\myaddin1\myaddin1\debug\excel.tlh(7354) : error C2238: ‘;’ の前に無効なトークンがあります。
c:\documents and settings\********\デスクトップ\myaddin1\myaddin1\debug\excel.tlh(28654) : warning C4003: マクロ ‘DialogBoxA’ に指定された実引数の数が少なすぎます。
c:\documents and settings\********\デスクトップ\myaddin1\myaddin1\debug\excel.tlh(28654) : error C2059: 構文エラー : ‘,’
これらは、Windows APIの関数名(マクロ名)とタイプライブラリに含まれるメソッド名がかぶってしまうことで発生してしまうようだ。これを回避するには次のようにauto_renameを指定し自動的に変更する(renameで一つずつ変更することもできる)。
1 2 3 4 5 6 7 |
// Office #import "libid:2DF8D04C-5BFA-101B-BDE5-00AA0044DE52" version("2.4") lcid("0") \ raw_interfaces_only named_guids auto_rename // Excel #import "libid:00020813-0000-0000-C000-000000000046" version("1.6") lcid("0") \ raw_interfaces_only named_guids auto_rename |
ちなみに、DialogBoxというメソッドは次のように変更された。
1 2 |
virtual HRESULT __stdcall DialogBox ( /*[out,retval]*/ VARIANT * RHS ) = 0; |
1 2 |
virtual HRESULT __stdcall __DialogBox ( /*[out,retval]*/ VARIANT * RHS ) = 0; |
LNK1179エラー
上記方法で名前の重複は解決できたが、ビルドを進めるとリンク段階で次のようなLNK1179というエラーが発生した。
リンクしています…
stdafx.obj : fatal error LNK1179: ファイルが無効か、または壊れています: COMDAT ‘_IID_Adjustments’ を複製します。
LNK1179というのはMSDNによると
オブジェクト モジュールには、同じ名前の COMDAT が 2 つ以上あります。
とのことである。どうも調べていくうちに、いくつかのタイプライブラリのヘッダ(tlh)で同じGUIDが定義されているのが原因のようだった。これの解決方法は、もし必要なGUDIがあればtlhから取り出してきてどこかに記述しておき、named_guidsを外せばよいようだ。最終的には、次のように記述した。
1 2 3 4 5 6 7 |
// Office #import "libid:2DF8D04C-5BFA-101B-BDE5-00AA0044DE52" version("2.4") lcid("0") \ raw_interfaces_only auto_rename // Word #import "libid:00020813-0000-0000-C000-000000000046" version("1.6") lcid("0") \ raw_interfaces_only auto_rename |