SimpleDLL,解決方案同名。#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),**跨語言調用必備**。#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;
}
SimpleDLLTest。..\SimpleDLL。..\SimpleDLL\Release\SimpleDLL.lib。#pragma comment(lib, "..\\SimpleDLL\\Release\\SimpleDLL.lib")。#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;
}
預設編譯依賴 MSVCR100.dll。獨立部署兩種方式:
重新編譯後,用 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" 生效。
[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);
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 或路徑錯誤 | 檢查附加相依性/庫目錄 |
| 運行時找不到 DLL | DLL 不在 PATH/輸出目錄 | 複製到 exe 同級或加入 PATH |
| 中文亂碼 | 編碼不匹配 | setlocale/CharSet/Encoding 統一 |
| C# 調用崩潰 | 調用約定/字符集/參數類型不匹配 | 核對 CallingConvention/Cdecl, CharSet.Ansi/Unicode |
| 依賴 MSVCR100.dll | 動態鏈接 CRT | 改 /MT 靜態鏈接 |
VS2010 建 DLL 核心三步:項目類型選 DLL → 導出宏切換 + extern "C" → 靜態鏈接 CRT 獨立部署。掌握此流程,即可生產跨語言、無依賴的原生組件。