錯誤: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 或宏防護防止重複包含。
- 線程函數建議做**類別靜態成員**,邏輯歸屬清晰、易存取共享資料。