fatal error LNK1120の対応方法について

解決


メグロ  2007-08-23 22:30:51  No: 66088

お世話になります。
ビルドエラーの対応方法についてご指導を宜しくお願い致します。

●Windows XP  VC++6  MFC  ダイアログベース

●エラー内容
error LNK2001: 外部シンボル "_xGetSystemMetrics@4" は未解決です
error LNK2001: 外部シンボル "_xGetMonitorInfo@8" は未解決です
error LNK2001: 外部シンボル "_xMonitorFromPoint@12" は未解決です
fatal error LNK1120: 外部参照 3 が未解決です。
link.exe の実行エラー

●以下の文法を追加で発生しました。
※テストとして別プロジェクトで実行時は、問題ありませんでした。

//Append Start
#include <multimon.h>
#define COMPILE_MULTIMON_STUBS
//Append End

BOOL CDIDSDlg::OnInitDialog()
{
// Append Start
    BOOL blRet = SetDidsDlg();
// Append End
}

BOOL CDIDSDlg::SetDidsDlg()
{
// Append Start
    CRect    crectDialog;
    RECT    rectDesktop;
    HMONITOR  MonitorHandle;
    MONITORINFO  MonitorInfo;

    // ダイアログサイズ
    GetWindowRect(&crectDialog);

    // 画面(プライマリ)サイズ:画面下タスクバーを除いたサイズ
    SystemParametersInfo(SPI_GETWORKAREA, 0, &rectDesktop, 0);

    // 画面(セカンダリ)サイズ
    POINT Point = {(long)rectDesktop.right, (long)rectDesktop.top};
    MonitorHandle = ::MonitorFromPoint(Point, MONITOR_DEFAULTTOPRIMARY);
    MonitorInfo.cbSize = sizeof(MonitorInfo);
    ::GetMonitorInfo(MonitorHandle, &MonitorInfo);

    // ダイアログの表示位置
    SetWindowPos(&wndTop, MonitorInfo.rcWork.left, MonitorInfo.rcWork.top, MonitorInfo.rcWork.right - MonitorInfo.rcWork.left, MonitorInfo.rcWork.bottom, SWP_SHOWWINDOW);
//Append END
    return(TRUE);
}


ポン太  2007-08-24 04:54:53  No: 66089

実行はしていませんが、
#include <multimon.h>
より、
#define COMPILE_MULTIMON_STUBS
が先なのではないでしょうか?

multimon.h
の最初に以下の文が書いてありますし、
// Exactly one source must include this with COMPILE_MULTIMON_STUBS defined.

146行目に
#ifdef COMPILE_MULTIMON_STUBS
があるので、インクルード前に定義しないとだめっぽいですね。


メグロ  2007-08-24 18:40:29  No: 66090

書き込みありがとうございます。
以下に変更して見ました。

<変更>
#define COMPILE_MULTIMON_STUBS
#include <multimon.h>

<結果>
error LNK2005: _InitMultipleMonitorStubs はすでに xx.obj で定義されています
error LNK2005: _xGetSystemMetrics@4 はすでに xx.obj で定義されています
fatal error LNK1169: 1 つ以上の複数回定義されているシンボルが見つかりました
link.exe の実行エラー

<その他>
この2行の定義の仕方に問題ありかなと思ってきました。
でも、調べ方がわかりません。
#define COMPILE_MULTIMON_STUBS
#include <multimon.h>


みい  2007-08-24 22:44:32  No: 66091

> ※テストとして別プロジェクトで実行時は、問題ありませんでした。
この時とインクルードする順番やインクルードしているファイルは
同じですか?


メグロ  2007-08-25 02:36:07  No: 66092

>この時とインクルードする順番やインクルードしているファイルは同じですか?

インクルードした順番
・テスト時は以下の順番です。
#define COMPILE_MULTIMON_STUBS
#include <multimon.h>

インクルードしているファイル
・本番用ではStdafx.hに以下が追加されています。
#include <afxsock.h>
#include <math.h>

・カメラを使用しているので、提供されたヘッダーファイルを
  使用しています。

情報不足の場合、ご指摘をお願いします。


メグロ  2007-08-25 02:52:44  No: 66093

以下の2行のみを、Stdafx.h, DIDS.h, DIDSDlg.cpp, DIDSDlg.hの
何れかに追加してリビルドしてもLNK2005が出ました。

#define COMPILE_MULTIMON_STUBS
#include <multimon.h>


ポン太  2007-08-25 05:29:15  No: 66094

複数回定義されている

と、あるので<multimon.h>が二回以上呼ばれているのではないでしょうか?
C/C++ は同じヘッダーを複数回読んだときの対策を自分で行わないといけません。
今後のレベルアップのために、
#ifdef #pragma once
などを調べてみてはいかがでしょうか?
(multimon.h 自身になぜ対策が施されていないかは疑問ですが)


yoh2  2007-08-25 10:01:25  No: 66095

> 今後のレベルアップのために、
> #ifdef #pragma once
> などを調べてみてはいかがでしょうか?
> (multimon.h 自身になぜ対策が施されていないかは疑問ですが)

これらによる複数回取り込み対策は、ひとつの翻訳単位に複数回同じヘッダの内容を
取り込まないようにするものです。
今回の問題は、複数の翻訳単位がCOMPILE_MULTIMON_STUBS付きでmultimon.hを取り
込むことにより、COMPILE_MULTIMON_STUBS が定義されている時にその定義が展開される
xGetSystemMetrics() などの関数を何度もコンパイルしてしまうことですのであまり
関係がありません。

ちなみに、試してはいませんが、ソースを読む限り、multimon.hは一翻訳単位内での
複数回取り込みの対策はしっかり行っているようです。

さて、ポン太さんが以前に引用されたmultimon.h内の記述

>> // Exactly one source must include this with COMPILE_MULTIMON_STUBS defined.

を見直してみましょう。
アプリケーション全体で *ひとつのソースだけ* がCOMPILE_MULTIMON_STUBS付きで
multimon.hを取り込むべし、とあります。
つまり、その他のソースでは、COMPILE_MULTIMON_STUBSを付けてはならないわけです。

COMPILE_MULTIMON_STUBS を付けてmultimon.hを取りこむソースとしては、
Stdafx.cpp (Stdafx.hではない) あたりが妥当ではないでしょうか。


メグロ  2007-08-27 22:13:06  No: 66096

#define COMPILE_MULTIMON_STUBS
#include <multimon.h>

をStdafx.cppに追加してみました

// stdafx.cpp : 標準インクルードファイルを含むソース ファイル
//              DIDS.pch : 生成されるプリコンパイル済ヘッダー
//              stdafx.obj : 生成されるプリコンパイル済タイプ情報

#include "stdafx.h"
// add start
#define COMPILE_MULTIMON_STUBS
#include <multimon.h>
// add end

リビルド後、以下のエラーが発生しました。

error C2065: 'HMONITOR' : 定義されていない識別子です。
error C2065: 'MONITORINFO' : 定義されていない識別子です。

multimon.hに以下の記載がありますが、関係ありかな???

// HMONITOR is already declared if _WIN32_WINNT >= 0x0500 in windef.h
// This is for components built with an older version number.
以下は、上記を翻訳
HMONITORは_WIN32_WINNT>windef.h Thisの=0×0500が旧式のバージョン番号で
造られたコンポーネントのためのものであるなら既に申告されます。


メグロ  2007-08-27 22:32:49  No: 66097

DIDSDlg.cppで以下を試してみました。

#ifndef DIDSDLG_CPP

#define DIDSDLG_CPP

#define COMPILE_MULTIMON_STUBS
#include <multimon.h>

#endif

エラーが発生しました。

error C2065: 'HMONITOR' : 定義されていない識別子です。
error C2065: 'MONITORINFO' : 定義されていない識別子です。


メグロ  2007-08-27 22:50:13  No: 66098

StdAfx.cpp追加時とDIDSDlg.cppへの追加時では若干エラー内容が違うので
エラー内容を記載します。

●StdAfx.cpp追加時
プロジェクト 'DIDS - Win32 Debug' 用の中間ファイルおよび出力ファイルを削除しています。
--------------------構成: DIDS - Win32 Debug--------------------
リソースをコンパイル中...
コンパイル中...
StdAfx.cpp
コンパイル中...
ClientSocket.cpp
DIDS.cpp
DIDSDlg.cpp
D:\〜\DIDSDlg.cpp(1245) : error C2065: 'HMONITOR' : 定義されていない識別子です。
D:\〜\DIDSDlg.cpp(1245) : error C2146: 構文エラー : ';' が、識別子 'MonitorHandle' の前に必要です。
D:\〜\DIDSDlg.cpp(1245) : error C2065: 'MonitorHandle' : 定義されていない識別子です。
D:\〜\DIDSDlg.cpp(1246) : error C2065: 'MONITORINFO' : 定義されていない識別子です。
D:\〜\DIDSDlg.cpp(1246) : error C2146: 構文エラー : ';' が、識別子 'MonitorInfo' の前に必要です。
D:\〜\DIDSDlg.cpp(1246) : error C2065: 'MonitorInfo' : 定義されていない識別子です。
D:\〜\DIDSDlg.cpp(1301) : error C2039: 'MonitorFromPoint' : '`global namespace'' のメンバではありません。
D:\〜\DIDSDlg.cpp(1301) : error C2065: 'MonitorFromPoint' : 定義されていない識別子です。
D:\〜\DIDSDlg.cpp(1301) : error C2065: 'MONITOR_DEFAULTTOPRIMARY' : 定義されていない識別子です。
D:\〜\DIDSDlg.cpp(1302) : error C2228: '.cbSize' : 左側がクラス、構造体、共用体ではありません。
D:\〜\DIDSDlg.cpp(1303) : error C2039: 'GetMonitorInfo' : '`global namespace'' のメンバではありません。
D:\〜\DIDSDlg.cpp(1303) : error C2065: 'GetMonitorInfo' : 定義されていない識別子です。
D:\〜\DIDSDlg.cpp(1309) : error C2228: '.rcWork' : 左側がクラス、構造体、共用体ではありません。
D:\〜\DIDSDlg.cpp(1309) : error C2228: '.left' : 左側がクラス、構造体、共用体ではありません。
D:\〜\DIDSDlg.cpp(1309) : error C2228: '.rcWork' : 左側がクラス、構造体、共用体ではありません。
D:\〜\DIDSDlg.cpp(1309) : error C2228: '.top' : 左側がクラス、構造体、共用体ではありません。
D:\〜\DIDSDlg.cpp(1309) : error C2228: '.rcWork' : 左側がクラス、構造体、共用体ではありません。
D:\〜\DIDSDlg.cpp(1309) : error C2228: '.right' : 左側がクラス、構造体、共用体ではありません。
D:\〜\DIDSDlg.cpp(1309) : error C2228: '.rcWork' : 左側がクラス、構造体、共用体ではありません。
D:\〜\DIDSDlg.cpp(1309) : error C2228: '.left' : 左側がクラス、構造体、共用体ではありません。
D:\〜\DIDSDlg.cpp(1309) : error C2228: '.rcWork' : 左側がクラス、構造体、共用体ではありません。
D:\〜\DIDSDlg.cpp(1309) : error C2228: '.bottom' : 左側がクラス、構造体、共用体ではありません。
Setting.cpp
コードを生成中...
cl.exe の実行エラー
DIDS.exe - エラー 22、警告 0

●DIDSDlg.cppへの追加時
プロジェクト 'DIDS - Win32 Debug' 用の中間ファイルおよび出力ファイルを削除しています。
--------------------構成: DIDS - Win32 Debug--------------------
リソースをコンパイル中...
コンパイル中...
StdAfx.cpp
コンパイル中...
ClientSocket.cpp
DIDS.cpp
DIDSDlg.cpp
c:\program files\microsoft visual studio\vc98\include\multimon.h(73) : error C2065: 'HMONITOR' : 定義されていない識別子です。
c:\program files\microsoft visual studio\vc98\include\multimon.h(73) : error C2275: 'HDC' : typedef 識別子に、クラス メンバ アクセス演算子 (->) を使用しました。
        c:\program files\microsoft visual studio\vc98\include\windef.h(239) : 'HDC' の宣言を確認してください。
c:\program files\microsoft visual studio\vc98\include\multimon.h(73) : error C2275: 'LPRECT' : typedef 識別子に、クラス メンバ アクセス演算子 (->) を使用しました。
        c:\program files\microsoft visual studio\vc98\include\windef.h(292) : 'LPRECT' の宣言を確認してください。
c:\program files\microsoft visual studio\vc98\include\multimon.h(73) : error C2275: 'LPARAM' : typedef 識別子に、クラス メンバ アクセス演算子 (->) を使用しました。
        c:\program files\microsoft visual studio\vc98\include\windef.h(171) : 'LPARAM' の宣言を確認してください。
c:\program files\microsoft visual studio\vc98\include\multimon.h(73) : error C2165: 'left-side modifier' : データへのポインタは変更できません。
c:\program files\microsoft visual studio\vc98\include\multimon.h(73) : error C2071: 'MONITORENUMPROC' : 記憶クラスは不正です。
c:\program files\microsoft visual studio\vc98\include\multimon.h(99) : error C2059: 構文エラー : '__stdcall'
c:\program files\microsoft visual studio\vc98\include\multimon.h(99) : error C2091: 関数は関数を返せません。
c:\program files\microsoft visual studio\vc98\include\multimon.h(99) : error C2501: 'HMONITOR' : 識別名を宣言するのに、型が指定されていません。
c:\program files\microsoft visual studio\vc98\include\multimon.h(99) : error C2373: 'HMONITOR' : 再定義されています。異なる型修飾子です。
c:\program files\microsoft visual studio\vc98\include\multimon.h(99) : error C2072: 'HMONITOR' : 関数を初期化しようとしました。
c:\program files\microsoft visual studio\vc98\include\multimon.h(100) : error C2059: 構文エラー : '__stdcall'
c:\program files\microsoft visual studio\vc98\include\multimon.h(100) : error C2091: 関数は関数を返せません。
c:\program files\microsoft visual studio\vc98\include\multimon.h(100) : error C2501: 'HMONITOR' : 識別名を宣言するのに、型が指定されていません。
c:\program files\microsoft visual studio\vc98\include\multimon.h(100) : error C2373: 'HMONITOR' : 再定義されています。異なる型修飾子です。
c:\program files\microsoft visual studio\vc98\include\multimon.h(100) : error C2072: 'HMONITOR' : 関数を初期化しようとしました。
c:\program files\microsoft visual studio\vc98\include\multimon.h(101) : error C2059: 構文エラー : '__stdcall'
c:\program files\microsoft visual studio\vc98\include\multimon.h(101) : error C2091: 関数は関数を返せません。
c:\program files\microsoft visual studio\vc98\include\multimon.h(101) : error C2501: 'HMONITOR' : 識別名を宣言するのに、型が指定されていません。
c:\program files\microsoft visual studio\vc98\include\multimon.h(101) : error C2373: 'HMONITOR' : 再定義されています。異なる型修飾子です。
c:\program files\microsoft visual studio\vc98\include\multimon.h(101) : error C2072: 'HMONITOR' : 関数を初期化しようとしました。
c:\program files\microsoft visual studio\vc98\include\multimon.h(102) : error C2629: 'int (' は不正です。
c:\program files\microsoft visual studio\vc98\include\multimon.h(114) : error C2065: 'g_pfnGetMonitorInfo' : 定義されていない識別子です。
c:\program files\microsoft visual studio\vc98\include\multimon.h(119) : error C2065: 'g_pfnMonitorFromWindow' : 定義されていない識別子です。
c:\program files\microsoft visual studio\vc98\include\multimon.h(120) : error C2065: 'g_pfnMonitorFromRect' : 定義されていない識別子です。
c:\program files\microsoft visual studio\vc98\include\multimon.h(121) : error C2065: 'g_pfnMonitorFromPoint' : 定義されていない識別子です。
c:\program files\microsoft visual studio\vc98\include\multimon.h(184) : error C2143: 構文エラー : ';' が '__stdcall' の前に必要です。
c:\program files\microsoft visual studio\vc98\include\multimon.h(184) : error C2501: 'HMONITOR' : 識別名を宣言するのに、型が指定されていません。
c:\program files\microsoft visual studio\vc98\include\multimon.h(196) : error C2143: 構文エラー : ')' が 'constant' の前に必要です。
c:\program files\microsoft visual studio\vc98\include\multimon.h(196) : error C2059: 構文エラー : ')'
c:\program files\microsoft visual studio\vc98\include\multimon.h(202) : error C2143: 構文エラー : ';' が '__stdcall' の前に必要です。
c:\program files\microsoft visual studio\vc98\include\multimon.h(202) : error C2501: 'HMONITOR' : 識別名を宣言するのに、型が指定されていません。
c:\program files\microsoft visual studio\vc98\include\multimon.h(202) : error C2086: 'HMONITOR' : 再定義されました。
        c:\program files\microsoft visual studio\vc98\include\multimon.h(202) : 'HMONITOR' の宣言を確認してください。
c:\program files\microsoft visual studio\vc98\include\multimon.h(214) : error C2143: 構文エラー : ')' が 'constant' の前に必要です。
c:\program files\microsoft visual studio\vc98\include\multimon.h(214) : error C2059: 構文エラー : ')'
c:\program files\microsoft visual studio\vc98\include\multimon.h(220) : error C2143: 構文エラー : ';' が '__stdcall' の前に必要です。
c:\program files\microsoft visual studio\vc98\include\multimon.h(220) : error C2501: 'HMONITOR' : 識別名を宣言するのに、型が指定されていません。
c:\program files\microsoft visual studio\vc98\include\multimon.h(220) : error C2086: 'HMONITOR' : 再定義されました。
        c:\program files\microsoft visual studio\vc98\include\multimon.h(220) : 'HMONITOR' の宣言を確認してください。
c:\program files\microsoft visual studio\vc98\include\multimon.h(229) : error C2143: 構文エラー : ')' が 'constant' の前に必要です。
c:\program files\microsoft visual studio\vc98\include\multimon.h(229) : error C2059: 構文エラー : ')'
c:\program files\microsoft visual studio\vc98\include\multimon.h(242) : error C2146: 構文エラー : ')' が、識別子 'hMonitor' の前に必要です。
c:\program files\microsoft visual studio\vc98\include\multimon.h(242) : warning C4229: 旧形式が使用されています : データの修飾子は無視されます。
c:\program files\microsoft visual studio\vc98\include\multimon.h(242) : error C2059: 構文エラー : ')'
c:\program files\microsoft visual studio\vc98\include\multimon.h(243) : error C2143: 構文エラー : ';' が '{' の前に必要です。
c:\program files\microsoft visual studio\vc98\include\multimon.h(243) : error C2447: 'PCH creation point' : 関数ヘッダがありません (旧形式の仮引数リスト?)
c:\program files\microsoft visual studio\vc98\include\multimon.h(328) : error C2143: 構文エラー : ')' が 'constant' の前に必要です。
c:\program files\microsoft visual studio\vc98\include\multimon.h(331) : error C2059: 構文エラー : ')'
D:\〜\DIDSDlg.cpp(1245) : error C2146: 構文エラー : ';' が、識別子 'MonitorHandle' の前に必要です。
D:\〜\DIDSDlg.cpp(1245) : error C2065: 'MonitorHandle' : 定義されていない識別子です。
Setting.cpp
コードを生成中...
cl.exe の実行エラー
DIDS.exe - エラー 48、警告 1


メグロ  2007-08-27 23:58:38  No: 66099

#include <windows.h>
を追加することにエラーを解消できました。
ポン太さん、みいさん、yoh2さん、ありがとうございました。
感謝です。<m(__)m>


メグロ  2007-08-28 00:25:00  No: 66100

間違いです。
処理がコメントのままでした。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






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