C查看动态库导出哪些函数以及动态库导出形式
目录
C++查看动态库导出哪些函数以及动态库导出形式
1、查看动态库导出哪些函数
1.1、在 Windows 和 Linux 上,可以使用不同的方法来查看动态库(.dll 或 .so)导出的函数
Windows:使用 dumpbin:Windows 提供了 dumpbin 工具(Visual Studio 自带),可以用于查看 .dll 导出的符号。
方法 1:使用 dumpbin
- 打开 x64/x86 Native Tools Command Prompt(VS 命令行工具)。
- 运行以下命令:
dumpbin /EXPORTS your_library.dll
- 会看到类似下面的输出:
Dump of file your_library.dll
Section contains the following exports:
00000000 characteristics
12345678 time date stamp
0.00 version
1 ordinal base
10 number of functions
10 number of names
ordinal hint RVA name
1 0 1234ABCD FunctionA
2 1 5678DCBA FunctionB
- 其中FunctionA 和 FunctionB 就是导出的函数。
- 可以看到如下例子:
E:\SteamTest\SteamSDK - 副本\SteamLogon\bin\Release>dumpbin /exports sdologinsdk.dll
- 输出:
E:\SteamTest\SteamSDK - 副本\SteamLogon\bin\Release>dumpbin /exports sdologinsdk.dll
Microsoft (R) COFF/PE Dumper Version 14.29.30151.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file sdologinsdk.dll
File Type: DLL
Section contains the following exports for sdologinsdk.dll
00000000 characteristics
67C7E536 time date stamp Wed Mar 5 13:46:30 2025
0.00 version
7 ordinal base
20 number of functions
5 number of names
ordinal hint RVA name
21 0 0000C320 DoLogin = _DoLogin
23 1 0000C630 GetAgreementStatus = _GetAgreementStatus
24 2 0000C4B0 GetLoginedCompanyId = _GetLoginedCompanyId
25 3 0000C5A0 OpenActivityWindow = _OpenActivityWindow
26 4 0000C4F0 SetGameClientType = _SetGameClientType
7 0000C240 [NONAME] _GhomeInitialize
8 0000C280 [NONAME] _GhomeShowLoginDialog
9 0000C2B0 [NONAME] _GhomeCloseLoginDialog
10 0000C5D0 [NONAME] _GhomeDoPrivacyAgreement
11 0000C680 [NONAME] _GhomeDoInit
12 0000C260 [NONAME] _GhomeSetOwnerWindow
13 0000C4C0 [NONAME] _GhomeSetLoginDialogState
14 0000C480 [NONAME] _GhomeOpenWindow
15 0000C300 [NONAME] _GhomeLogout
16 0000C370 [NONAME] _GhomeGetTicket
17 0000C6E0 [NONAME] _GhomeSetLoginArea
18 0000C700 [NONAME] _GhomeGetLoinAreaList
19 0000C350 [NONAME] _GhomeSetLoginMode
20 0000C2D0 [NONAME] _GhomeMoveLoginDialog
22 0000C340 [NONAME] _GHomeTerminal
Summary
8000 .data
2F000 .rdata
14000 .reloc
1000 .rsrc
F4000 .text
1000 .tls
E:\SteamTest\SteamSDK - 副本\SteamLogon\bin\Release>dumpbin /exports sdologinsdk.dll
Microsoft (R) COFF/PE Dumper Version 14.29.30151.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file sdologinsdk.dll
File Type: DLL
Section contains the following exports for sdologinsdk64.dll
00000000 characteristics
67C7E588 time date stamp Wed Mar 5 13:47:52 2025
0.00 version
1 ordinal base
20 number of functions
20 number of names
ordinal hint RVA name
1 0 0000C320 DoLogin = _DoLogin
2 1 0000C340 GHomeTerminal = _GHomeTerminal
3 2 0000C630 GetAgreementStatus = _GetAgreementStatus
4 3 0000C4B0 GetLoginedCompanyId = _GetLoginedCompanyId
5 4 0000C2B0 GhomeCloseLoginDialog = _GhomeCloseLoginDialog
6 5 0000C680 GhomeDoInit = _GhomeDoInit
7 6 0000C5D0 GhomeDoPrivacyAgreement = _GhomeDoPrivacyAgreement
8 7 0000C700 GhomeGetLoinAreaList = _GhomeGetLoinAreaList
9 8 0000C370 GhomeGetTicket = _GhomeGetTicket
10 9 0000C240 GhomeInitialize = _GhomeInitialize
11 A 0000C300 GhomeLogout = _GhomeLogout
12 B 0000C2D0 GhomeMoveLoginDialog = _GhomeMoveLoginDialog
13 C 0000C480 GhomeOpenWindow = _GhomeOpenWindow
14 D 0000C6E0 GhomeSetLoginArea = _GhomeSetLoginArea
15 E 0000C4C0 GhomeSetLoginDialogState = _GhomeSetLoginDialogState
16 F 0000C350 GhomeSetLoginMode = _GhomeSetLoginMode
17 10 0000C260 GhomeSetOwnerWindow = _GhomeSetOwnerWindow
18 11 0000C280 GhomeShowLoginDialog = _GhomeShowLoginDialog
19 12 0000C5A0 OpenActivityWindow = _OpenActivityWindow
20 13 0000C4F0 SetGameClientType = _SetGameClientType
Summary
8000 .data
2F000 .rdata
14000 .reloc
1000 .rsrc
F4000 .text
1000 .tls
E:\SteamTest\SteamSDK - 副本\SteamLogon\bin\Release>dumpbin /exports sdologinsdk.dll
Microsoft (R) COFF/PE Dumper Version 14.29.30151.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file sdologinsdk.dll
File Type: DLL
Section contains the following exports for sdologinsdk64.dll
00000000 characteristics
67C7EA7E time date stamp Wed Mar 5 14:09:02 2025
0.00 version
1 ordinal base
20 number of functions
20 number of names
ordinal hint RVA name
1 0 0000C1F0 DoLogin = _DoLogin
2 1 0000C210 GHomeTerminal = _GHomeTerminal
3 2 0000C500 GetAgreementStatus = _GetAgreementStatus
4 3 0000C380 GetLoginedCompanyId = _GetLoginedCompanyId
5 4 0000C180 GhomeCloseLoginDialog = _GhomeCloseLoginDialog
6 5 0000C550 GhomeDoInit = _GhomeDoInit
7 6 0000C4A0 GhomeDoPrivacyAgreement = _GhomeDoPrivacyAgreement
8 7 0000C5D0 GhomeGetLoinAreaList = _GhomeGetLoinAreaList
9 8 0000C240 GhomeGetTicket = _GhomeGetTicket
10 9 0000C110 GhomeInitialize = _GhomeInitialize
11 A 0000C1D0 GhomeLogout = _GhomeLogout
12 B 0000C1A0 GhomeMoveLoginDialog = _GhomeMoveLoginDialog
13 C 0000C350 GhomeOpenWindow = _GhomeOpenWindow
14 D 0000C5B0 GhomeSetLoginArea = _GhomeSetLoginArea
15 E 0000C390 GhomeSetLoginDialogState = _GhomeSetLoginDialogState
16 F 0000C220 GhomeSetLoginMode = _GhomeSetLoginMode
17 10 0000C130 GhomeSetOwnerWindow = _GhomeSetOwnerWindow
18 11 0000C150 GhomeShowLoginDialog = _GhomeShowLoginDialog
19 12 0000C470 OpenActivityWindow = _OpenActivityWindow
20 13 0000C3C0 SetGameClientType = _SetGameClientType
- Ghome.h:
#ifndef GHOME_H
#define GHOME_H
#include <windows.h>
#include <ObjBase.h>
#ifdef GHOME_EXPORTS
#define GHOME_API __declspec(dllexport)
#else
#define GHOME_API __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
#pragma pack(push,1)
// ======================== 错误码定义 ========================
#define SDOL_ERRORCODE_OK 0
#define SDOL_ERRORCODE_FAILED -1
#define SDOL_ERRORCODE_UNEXCEPT -100
#define SDOL_ERRORCODE_LOGINCANCEL -101
#define SDOL_ERRORCODE_INVALIDPARAM -102
#define SDOL_ERRORCODE_INVALIDBUFFER -103
#define SDOL_ERRORCODE_GETTICKET_TIMEOUT -104
#define SDOL_ERRORCODE_NOT_SUPPORT -105
// ======================== 登录模式 ========================
#define NormalLoginMode 0
#define LauncherLoginMode 1
#define AttachToLoginMode 2
// ======================== 更新动作 ========================
#define UPDATE_ACTION_DOWNLOAD 1
#define UPDATE_ACTION_SETUP 2
// ======================== 结构体定义 ========================
typedef struct GhomeLAppInfo {
DWORD Size; // = sizeof(GhomeLAppInfo)
int AppID; // 盛趣统一游戏ID
LPCWSTR AppName; // 游戏名称
LPCWSTR AppVer; // 游戏版本
int AreaId; // 游戏区ID (注意:不可用时传-1)
int GroupId; // 游戏组ID (注意:不可用时传-1)
} GhomeLAppInfo;
typedef struct SDOLLoginResult
{
DWORD Size; // sizeof(SDOLLoginResult),为以后扩充提供可能
LPCWSTR SessionId; // 用于后台验证的token串
LPCWSTR Sndaid; // 用户ID
LPCWSTR IdentityState; // 是否成年标识,0未成年,1成年
LPCWSTR Appendix; // 附加字段,保留
}GhomeSDOLLoginResult;
typedef struct GhomeLoginAreaMsg {
LPCWSTR Userid;
LPCWSTR Area;
LPCWSTR Group;
} GhomeLoginAreaMsg;
// ======================== 回调函数类型 ========================
typedef int (__cdecl *LPSDOLLOGINCALLBACKPROC)(int nErrorCode, const SDOLLoginResult* pLoginResult, int nUserData, int nReserved);
typedef BOOL (__cdecl *LPPRIVATEAGREEMENTCALLBACKPROC)(int nErrorCode, const char* call_condition);
typedef BOOL (__cdecl *LPGINITCALLBACKPROC)(int nErrorCode);
typedef BOOL (__cdecl *LPGGETLOGINAREALISTCALLBACKPROC)(int nErrorCode, const char* json_msg);
// ======================== DLL 导出函数 ========================
GHOME_API int __cdecl GhomeSetOwnerWindow(HWND hWnd);
GHOME_API int __cdecl GhomeShowLoginDialog(LPSDOLLOGINCALLBACKPROC fnCallback, int nUserData, int nReserved);
GHOME_API int __cdecl GhomeCloseLoginDialog(void);
GHOME_API int __cdecl GhomeMoveLoginDialog(int x, int y);
GHOME_API int __cdecl GhomeLogout(void);
GHOME_API int __cdecl GhomeSetLoginMode(int nLoginMode);
GHOME_API int __cdecl GhomeGetTicket(BSTR* bstrTicket);
GHOME_API int __cdecl GhomeOpenWindow(LPCWSTR pwcsWinType, LPCWSTR pwcsWinName, LPCWSTR pwcsSrc, int nLeft, int nTop, int nWidth, int nHeight, LPCWSTR pwcsMode);
GHOME_API int __cdecl GetLoginedCompanyId(void);
GHOME_API int __cdecl GhomeSetLoginDialogState(int nState);
GHOME_API int __cdecl SetGameClientType(LPCWSTR szGameClientType);
GHOME_API int __cdecl OpenActivityWindow(LPCWSTR pwcsWinType, LPCWSTR pwcsWinName, LPCWSTR pwcsSrc, int nLeft, int nTop, int nWidth, int nHeight, LPCWSTR pwcsMode);
GHOME_API int __cdecl GhomeDoPrivacyAgreement(const char* appId, LPPRIVATEAGREEMENTCALLBACKPROC fnCallback);
GHOME_API int __cdecl GhomeInitialize(const GhomeLAppInfo* pAppInfo);
GHOME_API int __cdecl GhomeDoInit(const char* appId, LPGINITCALLBACKPROC fnCallback);
GHOME_API int __cdecl GHomeTerminal();
GHOME_API int __cdecl GhomeSetLoginArea(const GhomeLoginAreaMsg* loginArea);
GHOME_API int __cdecl GhomeGetLoinAreaList(LPGGETLOGINAREALISTCALLBACKPROC fnCallback);
#pragma pack(pop)
#ifdef __cplusplus
}
#endif
#endif // GHOME_H
- Ghome.cpp
#define GHOME_EXPORTS
#include "Ghome.h"
#include "stdafx.h"
#include <comutil.h>
#include "SDOLInfo.h"
#include "GPlusManager.h"
#include "ModuleLoginSDK.h"
#include "IGMessageFilter.h"
// ======================== 主要导出函数 ========================
// 初始化
extern "C" GHOME_API int __cdecl GhomeInitialize(const GhomeLAppInfo* pAppInfo)
{
return ModuleLoginSDK::GetInstance()->SdoInitialize(*pAppInfo) ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
}
// 设置主窗口
extern "C" GHOME_API int __cdecl GhomeSetOwnerWindow(HWND hWnd)
{
return ModuleLoginSDK::GetInstance()->SetOwnerWindow(hWnd) ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
}
// 显示登录窗口
extern "C" GHOME_API int __cdecl GhomeShowLoginDialog(LPSDOLLOGINCALLBACKPROC fnCallback, int nUserData, int nReserved)
{
return ModuleLoginSDK::GetInstance()->ShowLoginDialog(fnCallback, nUserData, nReserved) ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
}
// 关闭登录窗口
extern "C" GHOME_API int __cdecl GhomeCloseLoginDialog(void)
{
return ModuleLoginSDK::GetInstance()->CloseLoginDialog() ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
}
// 移动登录窗口
extern "C" GHOME_API int __cdecl GhomeMoveLoginDialog(int x, int y)
{
return ModuleLoginSDK::GetInstance()->MoveLoginDialog(x, y) ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
}
// 用户注销
extern "C" GHOME_API int __cdecl GhomeLogout(void)
{
return ModuleLoginSDK::GetInstance()->Logout() ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
}
// 终止销毁接口
extern "C" GHOME_API int __cdecl GHomeTerminal()
{
return ModuleLoginSDK::Destroy() == ShutdownSuccess ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
}
// 设置登录模式
extern "C" GHOME_API int __cdecl GhomeSetLoginMode(int nLoginMode)
{
return ModuleLoginSDK::GetInstance()->SetLoginMode(nLoginMode) ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
}
// 获取登录票据
extern "C" GHOME_API int __cdecl GhomeGetTicket(BSTR* bstrTicket)
{
std::string strTicket;
std::string strSndaId;
if (!ModuleLoginSDK::GetInstance()->GetTicket(strTicket, strSndaId))
{
return SDOL_ERRORCODE_FAILED;
}
*bstrTicket = _com_util::ConvertStringToBSTR(strTicket.c_str());
return SDOL_ERRORCODE_OK;
}
// 打开窗口
extern "C" GHOME_API int __cdecl GhomeOpenWindow(LPCWSTR pwcsWinType, LPCWSTR pwcsWinName, LPCWSTR pwcsSrc, int nLeft, int nTop, int nWidth, int nHeight, LPCWSTR pwcsMode)
{
return ModuleLoginSDK::GetInstance()->OpenWindow(pwcsWinType, pwcsWinName, pwcsSrc, nLeft, nTop, nWidth, nHeight, pwcsMode) == 0 ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
}
// 获取已登录公司ID
extern "C" GHOME_API int __cdecl GetLoginedCompanyId(void)
{
return ModuleLoginSDK::GetInstance()->GetLoginedCompanyId();
}
// 设置登录窗口状态
extern "C" GHOME_API int __cdecl GhomeSetLoginDialogState(int nState)
{
if (nState != 1 && nState != 2)
{
return SDOL_ERRORCODE_FAILED;
}
return ModuleLoginSDK::GetInstance()->SetLoginDialogState(nState) ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
}
// 设置游戏客户端类型
extern "C" GHOME_API int __cdecl SetGameClientType(LPCWSTR szGameClientType)
{
if (szGameClientType == NULL)
{
return SDOL_ERRORCODE_FAILED;
}
ModuleLoginSDK::GetInstance()->SetGameClientType(StringHelper::UnicodeToANSI(szGameClientType));
return SDOL_ERRORCODE_OK;
}
// 游戏内打开活动窗口
extern "C" GHOME_API int __cdecl OpenActivityWindow(LPCWSTR pwcsWinType, LPCWSTR pwcsWinName, LPCWSTR pwcsSrc, int nLeft, int nTop, int nWidth, int nHeight, LPCWSTR pwcsMode)
{
return ModuleLoginSDK::GetInstance()->OpenActivityWindow(pwcsWinType, pwcsWinName, pwcsSrc, nLeft, nTop, nWidth, nHeight, pwcsMode) == 0 ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
}
// 处理隐私协议
extern "C" GHOME_API int __cdecl GhomeDoPrivacyAgreement(const char* appId, LPPRIVATEAGREEMENTCALLBACKPROC fnCallback)
{
return ModuleLoginSDK::GetInstance()->doPrivacyAgreement(appId, fnCallback) ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
}
// 获取隐私协议状态
extern "C" GHOME_API int __cdecl GetAgreementStatus(const char* appId)
{
return ModuleLoginSDK::GetInstance()->getAgreementStatus(appId) ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
}
// 执行初始化
extern "C" GHOME_API int __cdecl GhomeDoInit(const char* appId, LPGINITCALLBACKPROC fnCallback)
{
return ModuleLoginSDK::GetInstance()->initialize(appId, fnCallback) ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
}
// 设置登录区服
extern "C" GHOME_API int __cdecl GhomeSetLoginArea(const GhomeLoginAreaMsg* loginArea)
{
return ModuleLoginSDK::GetInstance()->SetLoginArea(loginArea) ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
}
// 获取区服列表
extern "C" GHOME_API int __cdecl GhomeGetLoinAreaList(LPGGETLOGINAREALISTCALLBACKPROC fnCallback)
{
return ModuleLoginSDK::GetInstance()->GetLoginArea(fnCallback) ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
}
- sdk.def
LIBRARY sdologinsdk
EXPORTS
GhomeInitialize
GhomeSetOwnerWindow
GhomeShowLoginDialog
GhomeCloseLoginDialog
GhomeMoveLoginDialog
GhomeLogout
GHomeTerminal
GhomeSetLoginMode
GhomeGetTicket
GhomeOpenWindow
GetLoginedCompanyId
GhomeSetLoginDialogState
SetGameClientType
OpenActivityWindow
GhomeDoPrivacyAgreement
GetAgreementStatus
GhomeDoInit
GhomeSetLoginArea
GhomeGetLoinAreaList
- 是的,直接使用 .def 文件指定导出函数名称 是最干净、最推荐的方法之一!🎯
- 📌
这样做的好处:
避免了调用约定 (__cdecl vs __stdcall) 影响导出名称:
- __stdcall 默认会在导出名称后加 @参数字节数,__cdecl 会前面加 _。
- . def 文件直接指定 你想要的导出名称,不管编译器怎么修饰符号,它都会按照 .def 里的导出名称使用。
导出名称更清晰,调用方容易匹配:
- 你用 dumpbin /exports sdologinsdk.dll 看到的导出名称就是 .def 里指定的,保证不会有 _ 或 @ 这种额外修饰。
兼容不同的调用约定:
- 即使某些函数是 __stdcall,某些是 __cdecl,都不会影响导出名称,调用者无需关心函数的调用约定。
- Linux/macOS:使用 nm 和 objdump:Linux 和 macOS 使用 nm 或 objdump 来查看 .so 共享库的导出符号。
- 方法 1:使用 nm :
nm -D your_library.so
- 输出示例:
0000000000001234 T exported_function
0000000000005678 T another_exported_function
- 带 T 标记的符号就是导出的函数。
2、Windows 调用约定(Calling Convention)导致的符号修饰(Name Mangling)
- 在 Windows 平台,调用约定(Calling Convention)决定了:
- 函数参数如何传递(寄存器还是栈)。
- 栈由谁来清理(调用者还是被调用者)。
- 编译器如何修饰(Mangle)函数名称。
2.1、 常见调用约定及其符号修饰
Windows 下常见的调用约定有:
2.2、调用约定导致的符号修饰
在 Windows 下,导出的 C 语言函数名称会经过 符号修饰(Name Mangling),不同调用约定会导致不同的符号格式。
1️⃣ __cdecl(默认 C/C++ 约定):
规则:
- 参数从右到左压入栈。
- 调用者清理堆栈。
- 符号修饰:前面加 _ 。
示例:
extern "C" __cdecl int MyFunction(int a, int b);
编译后(dumpbin /exports):
- _MyFunction
注意: __cdecl 没有参数字节数,因为它由调用者清理堆栈,编译器不需要记录参数大小。
2️⃣ __stdcall(Windows API 默认,CALLBACK):
- 规则:
- 参数从右到左压入栈。
- 被调用者清理堆栈。
- 符号修饰:前面加 _,后面加 @参数字节数。
- 规则:
示例:
extern "C" __stdcall int MyFunction(int a, int b);
- 编译后(dumpbin /exports):
? _MyFunction@8
因为 int 类型参数各占 4 字节,所以 @8 代表 2 * 4 = 8 字节。
3️⃣ __fastcall(寄存器优化):
规则:
- 前两个参数放 ECX 和 EDX,其余从右到左入栈。
- 被调用者清理堆栈。
- 符号修饰:前面加 @,后面加 @参数字节数。
示例:
extern "C" __fastcall int MyFunction(int a, int b);
- 编译后(dumpbin /exports):
@MyFunction@8
- 4️⃣ __vectorcall(用于 SIMD 寄存器优化):
- 规则:
- 优先使用 SIMD/寄存器
- 被调用者清理堆栈
- 符号修饰:前面加 ?,后面加 @参数字节数
- 示例:
extern "C" __vectorcall int MyFunction(int a, int b);
- 编译后(dumpbin /exports):
MyFunction@@16
- 5️⃣ __thiscall(C++ 类成员函数默认调用约定):
- 规则
- this 指针通过 ECX 传递
- 其他参数从右到左入栈
- 被调用者清理堆栈
- 符号修饰:C++ 方式(如 _MethodName@8)
- 示例:
class MyClass {
public:
int __thiscall MyMethod(int a, int b);
};
- 编译后(dumpbin /exports):
MyMethod@MyClass@8
- 如果 不是 extern “C”,C++ 还会加上类名。
2.3. 为什么 _GHomeTerminal 会多 _ 或 @16
- 如果 GHomeTerminal 使用 __cdecl,应该导出:
_GHomeTerminal
- 如果 GHomeTerminal 使用 __stdcall,会变成:
_GHomeTerminal@0
- (因为没有参数,所以 @0)。
- 如果你的 dumpbin /exports 看到 _GHomeTerminal,但期望 GHomeTerminal:
- 你使用了 __cdecl,但 dllimport/dllexport 期望 __stdcall。
- 你应该 明确使用 __stdcall 或者 .def 文件控制导出名称。
2.4、解决导出名称问题
- ✅
方法 1:在 .def 文件里指定名称:
- 在 sdologinsdk.def 里指定:
LIBRARY sdologinsdk
EXPORTS
GHomeTerminal
- 这样不管调用约定是什么,导出的函数都会是 GHomeTerminal。
- 方法 2:确保 __cdecl 和 __stdcall 一致:
extern "C" __stdcall int GHomeTerminal();
如果你的代码用的是 __stdcall,但 dumpbin 里是 _GHomeTerminal,说明 dllimport/dllexport 期望的是 __stdcall。
✅ 方法 3:如果必须用 __cdecl,在 .def 里强制去掉 _:
- 如果 dumpbin /exports 里看到 _GHomeTerminal,但你想让导出的名称是 GHomeTerminal,可以在 .def 里这样写:
EXPORTS
GHomeTerminal=_GHomeTerminal
- 这样 dll 里存的是 _GHomeTerminal,但外部调用者只看到 GHomeTerminal。