首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

MFC 大量巨集定義 LNK2005 重複定義:頭文件防護與線程函數位置

     編輯:程式設計疑難解答

錯誤:LNK2005 符號在多個 .obj 中重複定義


error LNK2005: "struct Zeni_MTS_Rolypon_InOut InOutRoly" (?InOutRoly@@3UZeni_MTS_Rolypon_InOut@@A) already defined in bowei.obj

原因:頭文件中定義了**全域變數/函數實作**,被多個 .cpp include


// Common.h ❌ 錯誤示範
#define MAX 100
struct Zeni_MTS_Rolypon_InOut InOutRoly; // 定義實體 → 每個 include 產生一份
void ThreadFunc() { ... }                // 函數實作 → 重複定義

修正:頭文件只**宣告**,實作放在 .cpp


// Common.h ✅
#pragma once  // 或傳統 #ifndef COMMON_H #define COMMON_H ... #endif
#define MAX 100
extern struct Zeni_MTS_Rolypon_InOut InOutRoly; // 宣告
void ThreadFunc();                               // 宣告

// Common.cpp ✅
#include "Common.h"
struct Zeni_MTS_Rolypon_InOut InOutRoly; // 唯一定義
void ThreadFunc() { ... }                // 唯一實作

MFC 線程函數放哪裡?

類型位置呼叫方式
全域函數任意 .cpp(如 ThreadFunc.cpp)AfxBeginThread(ThreadFunc, param)
靜態成員函數類別內 static UINT ThreadFunc(LPVOID)AfxBeginThread(&MyClass::ThreadFunc, param)
類別成員函數(非靜態)不可直接用需包裝靜態函數傳 this

常見模式:CWinApp 派生類中管理線程


// MyApp.h
class CMyApp : public CWinApp {
public:
    static UINT WorkerThread(LPVOID pParam);
    CWinThread* m_pThread;
};

// MyApp.cpp
UINT CMyApp::WorkerThread(LPVOID pParam) {
    // 可存取 theApp.m_pThread 等
    return 0;
}

// 啟動
theApp.m_pThread = AfxBeginThread(CMyApp::WorkerThread, this);

總結

  • 頭文件**只放宣告**(extern、函數原型、類別定義),**不放定義/實作**。
  • 加 #pragma once 或宏防護防止重複包含。
  • 線程函數建議做**類別靜態成員**,邏輯歸屬清晰、易存取共享資料。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved