目录

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,都不会影响导出名称,调用者无需关心函数的调用约定。

https://i-blog.csdnimg.cn/direct/ce7605dfedeb4676981e9c7a7faf6e3b.png

https://i-blog.csdnimg.cn/direct/6bb16ace77384c85b65cf5373ab5d4bb.png

https://i-blog.csdnimg.cn/direct/c6f4180c4f8f4e838e0103b2fbd1495a.png

  • 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 标记的符号就是导出的函数。
  • https://i-blog.csdnimg.cn/direct/7066ddacf6874c3ca85bde38f45f6d8a.png

2、Windows 调用约定(Calling Convention)导致的符号修饰(Name Mangling)

  • 在 Windows 平台,调用约定(Calling Convention)决定了:
    • 函数参数如何传递(寄存器还是栈)。
    • 栈由谁来清理(调用者还是被调用者)。
    • 编译器如何修饰(Mangle)函数名称。

2.1、 常见调用约定及其符号修饰

  • Windows 下常见的调用约定有:

    https://i-blog.csdnimg.cn/direct/e8e75c1480414f7580364cfd5eefbd6b.png

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。

3、总结

https://i-blog.csdnimg.cn/direct/fd2326b555e4438caf7063e80fde8207.png