首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Windows 程式設計入門(六):更換入口點與連結器錯誤深度剖析

     編輯:關於C語言

案例:將 main 改為 myentry

#include <stdio.h>

int myentry() {
    printf("hello world");
    return 0;
}

編譯 cl /c hello.c 成功產生 hello.obj;連結 link hello.obj 報錯:

LIBC.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
hello.exe : fatal error LNK1120: 1 unresolved externals

錯誤推導邏輯

  1. cl 未加 /Zl,hello.obj 內含兩個 defaultlib 指示:libc.lib 與 oldnames.lib。
  2. 連結器載入 libc.lib,其中包含 crt0.obj(來自 crt0.c),定義了 mainCRTStartup。
  3. mainCRTStartup 內部呼叫 main,但 hello.obj 只定義 myentry,缺少 _main 符號 → LNK2001。

關鍵觀念:連結階段必須解析所有符號

與編譯階段不同,連結器要求所有外部符號皆須解析,即使該函式在執行路徑上永不被呼叫。示例:

int myentry() { printf("hello world"); return 0; }
int main() { myentry(); }
int test() { nofunc(); return 0; } // test 未被呼叫,nofunc 未定義

連結仍報錯 unresolved external symbol _nofunc。這是 C/C++ 編譯模型(編譯→連結→執行三階段)特有的複雜性。

實驗三種解決路徑

方式編譯指令連結指令結果
Way1:改回 maincl /c /Zl hello.clink hello.obj缺 _printf、_mainCRTStartup
Way2:指定 entry=myentrycl /c /Zl hello.clink /entry:myentry hello.obj錯 LNK1221:無法推斷 subsystem
Way2+subsystemcl /c /Zl hello.clink /entry:myentry /subsystem:console hello.obj缺 _printf
Way3:main + entry=maincl /c /Zl hello.clink /entry:main /subsystem:console hello.obj缺 _printf

錯誤代碼速查

  • LNK2001:未解析的外部符號(函式/變數/標籤)
  • LNK1561:找不到入口點(需 /ENTRY 或提供 main/WinMain 等)
  • LNK1221:無法推斷 subsystem,需加 /SUBSYSTEM:CONSOLE 或 WINDOWS

核心心法

連結器根據 defaultlib、/ENTRY、/SUBSYSTEM、符號定義/引用關係,自動推導或強制指定程式屬性。理解這套規則,才能在「脫離 IDE」時精準控制輸出。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved