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

從 Visual Studio 提取命令行編譯工具鏈構建類 GCC 環境編譯 C 程序為 DLL

     編輯:關於C語言

背景動機

習慣 Linux GCC 命令行編譯流程,但在 Windows 需要用 MSVC 編譯 DLL。Visual Studio 安裝體積龐大,若只需命令行編譯器,可提取核心文件構建輕量級工具鏈,類似 MinGW 但使用官方 MSVC 編譯器,保證 ABI 兼容性。

提取步驟詳解

1. 準備目錄結構


D:\vctool\
├── bin\       # 編譯器 cl.exe、鏈接器 link.exe 等
├── include\   # 標準庫頭文件
├── lib\       # MSVC 庫文件
└── sdklib\    # Windows SDK 庫文件

2. 文件複製來源

目標目錄來源路徑 (VS 2019/2022 典型路徑)
binVC\Tools\MSVC\14.xx.xxxxxx\bin\Hostx64\x64\
includeVC\Tools\MSVC\14.xx.xxxxxx\include\
libVC\Tools\MSVC\14.xx.xxxxxx\lib\x64\
sdklibWindows Kits\10\Lib\10.0.xxxxxx\um\x64\

注意:SDK 庫單獨放 sdklib 避免覆蓋 MSVC 庫,後續鏈接時需同時指定兩個路徑。

3. 環境變量配置

將 D:\vctool\bin 加入系統 PATH,或在編譯腳本中臨時設置。

測試代碼:導出函數的 DLL


// Test.c
#include <stdio.h>

__declspec(dllexport) int sum(int a, int b) {
    return a + b;
}

__declspec(dllexport) void hello() {
    puts("Hello from MSVC DLL!");
}

編譯腳本:build.bat


@echo off
setlocal

:: 工具鏈路徑
set VCTOOL=D:\vctool
set PATH=%VCTOOL%\bin;%PATH%
set INCLUDE=%VCTOOL%\include
set LIB=%VCTOOL%\lib;%VCTOOL%\sdklib

:: 編譯為目標文件
cl /c Test.c
if errorlevel 1 exit /b 1

:: 鏈接為 DLL
link /dll Test.obj /out:Test.dll
if errorlevel 1 exit /b 1

echo 成功生成: Test.dll, Test.lib, Test.exp
pause

常見錯誤與解決

錯誤信息原因解決
找不到 mspdb140.dll / mspdbcore.dllPDB 服務 DLL 缺失從 VS 安裝目錄複製到 bin 目錄
LINK: fatal error LNK1104: 無法打開 kernel32.libSDK 庫路徑缺失確認 sdklib 已複製且 LIB 包含該路徑
cl: 命令行錯誤 D8003: 缺少源文件名工作目錄錯誤cd 到源文件目錄再運行 build.bat
未解析的外部符號缺少庫或調用約定不匹配檢查 __declspec(dllexport)、.def 文件、LIB 路徑

cl.exe 核心選項速查


/c           僅編譯不鏈接,生成 .obj
/Zs          語法檢查不生成文件
/I 路徑      添加頭文件搜索路徑
/D 宏        定義預處理器宏
/MD          使用動態運行庫 MSVCRT.dll (發布推薦)
/MT          使用靜態運行庫 libcmt.lib
/O2          速度優化
/Ob2         內聯優化
/Wall        最高警告級別
/WX          警告視為錯誤
/EHsc        C++ 異常處理模型
/TC          強制作為 C 源文件編譯
/TP          強制作為 C++ 源文件編譯
/Fo文件名    指定輸出 .obj 文件名

link.exe 核心選項速查


/dll                 生成 DLL
/out:文件名          指定輸出文件名
/libpath:路徑        添加庫搜索路徑
/machine:x64         目標架構
/def:文件.def        模塊定義文件導出符號
/export:函數名       命令行指定導出
/entry:函數名        入口點 (DLL 默認 DllMain)
/subsystem:console   控制台子系統
/subsystem:windows   GUI 子系統
/opt:ref             移除未引用數據/函數
/opt:icf             合併相同函數

進階:使用 .def 文件導出


; Test.def
LIBRARY Test
EXPORTS
    sum
    hello

link /dll Test.obj /def:Test.def /out:Test.dll

.def 文件優勢:不污染源碼、支持序數導出、重命名導出、數據導出。

自動化構建:CMake 整合


# CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(TestDLL LANGUAGES C)

# 指定 MSVC 工具鏈 (可選,通常自動檢測)
# set(CMAKE_C_COMPILER "D:/vctool/bin/cl.exe")

add_library(Test SHARED Test.c)
set_target_properties(Test PROPERTIES
    WINDOWS_EXPORT_ALL_SYMBOLS ON  # 自動導出所有符號 (類 GCC)
)

CMake 會自動調用 cl/link,生成 Visual Studio 解決方案或直接構建,比手寫 bat 更可維護。

對比:MinGW-w64 vs MSVC 提取版

維度MinGW-w64MSVC 提取版
ABI 兼容性GNU/MinGW原生 MSVC (Windows 系統組件標準)
C 標準支持C11/C17 較好C11/C17 部分,C18 改進中
調試器支持GDBWinDbg / VS Debugger (最佳)
運行庫依賴msvcrt.dll (系統) 或 ucrtbase.dllvcruntime140.dll + ucrtbase.dll
授權GPL/LGPLVisual Studio 授權條款
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved