C++/CLIで妙なリンクエラー(LNK2034)

VisualStudio 2012の環境で、C++/CLI でのDLLを作成していたところ、妙なリンクエラーに出逢いました。このDLLは他のC/C++のライブラリをリンクして、C#から扱うためのラッパーとして機能するものです。以前は VisualStudio 2008 の環境でコンパイルさせていました。

エラーの内容はこんな感じです。一部省略していますが。

1>MSVCMRTD.lib(mstartup.obj) : error LNK2022: メタデータの操作に失敗しました (80131195) : カスタム属性が適合しません: (0x0c0001e7)。
1>MSVCMRTD.lib(mstartup.obj) : error LNK2022: メタデータの操作に失敗しました (80131195) : カスタム属性が適合しません: (0x0c0001e9)。
1>MSVCMRTD.lib(managdeh.obj) : error LNK2022: メタデータの操作に失敗しました (80131195) : カスタム属性が適合しません: (0x0c000086)。
1>MSVCMRTD.lib(managdeh.obj) : error LNK2022: メタデータの操作に失敗しました (80131195) : カスタム属性が適合しません: (0x0c000089)。
1>MSVCMRTD.lib(mehvecdtr.obj) : error LNK2022: メタデータの操作に失敗しました (80131195) : カスタム属性が適合しません: (0x0c000083)。
1>MSVCMRTD.lib(mehvecdtr.obj) : error LNK2022: メタデータの操作に失敗しました (80131195) : カスタム属性が適合しません: (0x0c000087)。

...

1>LINK : error LNK2034: metadata は、COFF シンボル テーブルと整合しません: シンボル '?free@@$$J0YAXPAX@Z' (0600098B) には、(0A0000C4) を伴う矛盾するメタデータが MSVCMRTD.lib(locale0_implib.obj) で指定されています。
1>LINK : error LNK2034: metadata は、COFF シンボル テーブルと整合しません: シンボル '?__ExceptionPtrCopy@@$$FYAXPAXPBX@Z' (060009D0) には、(0A0000CF) を伴う矛盾するメタデータが MSVCMRTD.lib(locale0_implib.obj) で指定されています。
1>LINK : error LNK2034: metadata は、COFF シンボル テーブルと整合しません: シンボル '??0_Lockit@std@@$$FQAE@H@Z' (0600085B) には、(0A0000D2) を伴う矛盾するメタデータが MSVCMRTD.lib(locale0_implib.obj) で指定されています。
1>LINK : error LNK2034: metadata は、COFF シンボル テーブルと整合しません: シンボル '??1_Lockit@std@@$$FQAE@XZ' (0600085C) には、(0A0000D3) を伴う矛盾するメタデータが MSVCMRTD.lib(locale0_implib.obj) で指定されています。
1>LINK : error LNK2034: metadata は、COFF シンボル テーブルと整合しません: シンボル '?_Debug_message@std@@$$FYAXPB_W0I@Z' (0600085E) には、(0A0000DD) を伴う矛盾するメタデータが MSVCMRTD.lib(locale0_implib.obj) で指定されています。
1>LINK : fatal error LNK1255: メタデータエラーのためにリンクに失敗しました。

初めて出遭ったエラーで難航しましたが、原因と解決策は見つかりました。

原因/解決策

使用しているスタティックライブラリにおいて、_WIN32_WINNT マクロがヘッダで指定されてコンパイルされていました。このとき、対象をWindows XPに絞っていたためか即値セットでした。これをそのままVisual Studio 2012の環境でコンパイルしたため、_WIN32_WINNT の値がC/C++ライブラリとC++/CLIのプロジェクトでのリンクフェーズとで食い違ったため、このようなエラーが発生したと考えられます。
試しにC/C++側のライブラリにおいては、_WIN32_WINNT を定義しないようにして、VisualStudio 2012の指定に従うようにしてみたところ、このエラーは発生しなくなりました。
 おそらく、Windowsの各構造体のサイズがこの変更で合うようになったためではないかと考えています。従来はここがネイティブとC#側とのマーシャリングで失敗したため、このようなエラーメッセージとして現れたのではないかと思っています。定義と実体が食い違っている、という状況でしょうか。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする