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

VS2010 創建 C++ 動態鏈接庫 (DLL) 完整教程:從項目建立到跨語言調用

     編輯:C++ 入門

第一部分:創建 DLL 項目

  1. 文件 → 新建 → 項目 → Visual C++ → Win32 專案。
  2. 名稱 SimpleDLL,解決方案同名。
  3. 嚮導選「DLL」+「空專案」。

第二部分:添加導出類

頭文件 SimpleDLL.h

#pragma once

#ifdef DLL_IMPLEMENT
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif

extern "C" DLL_API int add(int x, int y);
extern "C" DLL_API const wchar_t* getPlayUrl(const wchar_t* mgrIp, long mgrPort, long materialId);
extern "C" DLL_API const char* getUrl(const char* mgrIp, long mgrPort, long materialId);

關鍵點:

  • DLL_IMPLEMENT 僅在 DLL 內部定義(cpp 前),實現導出/導入自動切換。
  • extern "C" 禁用 C++ 名稱修飾,使導出函數名保持原樣(add 而非 ?add@@YAHHH@Z),**跨語言調用必備**。
  • 寬字符/窄字符版本並存,滿足不同調用方需求。

源文件 SimpleDLL.cpp

#define DLL_IMPLEMENT
#include "SimpleDLL.h"
#include 
#include 
#include 

int DLL_API add(int x, int y) { return x + y; }

DLL_API const wchar_t* getPlayUrl(const wchar_t* mgrIp, long mgrPort, long) {
    static wchar_t url[260] = {0};
    wcscpy_s(url, L"https://中文");
    wcscat_s(url, mgrIp);
    wcscat_s(url, L":");
    wchar_t port[20]; _ltow_s(mgrPort, port, 10);
    wcscat_s(url, port);
    return url;
}

DLL_API const char* getUrl(const char* mgrIp, long mgrPort, long) {
    static char url[260] = {0};
    strcpy_s(url, "https://中文");
    strcat_s(url, mgrIp);
    strcat_s(url, ":");
    char port[20]; _ltoa_s(mgrPort, port, 10);
    strcat_s(url, port);
    return url;
}

第三部分:創建測試控制台程序

  1. 方案右鍵 → 添加 → 新專案 → Win32 控制台應用程式 SimpleDLLTest。
  2. 專案屬性 → C/C++ → 常規 → 附加包含目錄加入 ..\SimpleDLL。
  3. 鏈接器 → 輸入 → 附加相依性加入 ..\SimpleDLL\Release\SimpleDLL.lib。
  4. 或源碼中用 #pragma comment(lib, "..\\SimpleDLL\\Release\\SimpleDLL.lib")。

SimpleDLLTest.cpp

#include "stdafx.h"
#include "../SimpleDLL/SimpleDLL.h"
#include 
#include 

int _tmain() {
    setlocale(LC_ALL, "chs");  // 支持中文輸出
    wprintf(L"getPlayUrl: %s\n", getPlayUrl(L"127.0.0.1", 10087, 1));
    printf("getUrl: %s\n", getUrl("127.0.0.1", 10087, 1));
    system("pause");
    return 0;
}

第四部分:去除 MSVCR 依賴(獨立部署)

預設編譯依賴 MSVCR100.dll。獨立部署兩種方式:

  1. 靜態鏈接 CRT:專案屬性 → C/C++ → 代碼生成 → 運行庫選 多執行緒 (/MT)(Release)或 多執行緒偵錯 (/MTd)(Debug)。
  2. MFC 靜態鏈接:專案屬性 → 常規 → MFC 的使用 → 在靜態庫中使用 MFC。

重新編譯後,用 Dependency Walker 確認無 MSVCR100.dll 依賴。

第五部分:驗證導出函數名

用 dumpbin /exports SimpleDLL.dll 或 Dependency Walker 查看導出表:

ordinal hint RVA      name
      1    0 00001000 add
      2    1 00001010 getPlayUrl
      3    2 00001020 getUrl

函數名無修飾,確認 extern "C" 生效。

第六部分:C# / Java / Python 調用示例

C# (P/Invoke)

[DllImport("SimpleDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int add(int x, int y);

[DllImport("SimpleDLL.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern string getUrl(string ip, int port, int id);

Python (ctypes)

from ctypes import cdll, c_int, c_char_p
dll = cdll.LoadLibrary("SimpleDLL.dll")
dll.add.argtypes = [c_int, c_int]
dll.add.restype = c_int
print(dll.add(3, 5))

常見坑點總結

現象原因解決
LNK2019 無法解析外部符號未鏈接 .lib 或路徑錯誤檢查附加相依性/庫目錄
運行時找不到 DLLDLL 不在 PATH/輸出目錄複製到 exe 同級或加入 PATH
中文亂碼編碼不匹配setlocale/CharSet/Encoding 統一
C# 調用崩潰調用約定/字符集/參數類型不匹配核對 CallingConvention/Cdecl, CharSet.Ansi/Unicode
依賴 MSVCR100.dll動態鏈接 CRT改 /MT 靜態鏈接

總結

VS2010 建 DLL 核心三步:項目類型選 DLL → 導出宏切換 + extern "C" → 靜態鏈接 CRT 獨立部署。掌握此流程,即可生產跨語言、無依賴的原生組件。

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