• typedef复杂函数接口的解释


    typedef定义函数解释interface.h接口

    在这里插入图片描述

    typedef int (WINAPI* LPSDOLInitialize)(const SDOLAppInfo* pAppInfo);
    typedef int (WINAPI* LPSDOLGetModule)(REFIID riid, void** intf);
    typedef int (WINAPI* LPSDOLTerminal)();

    LPSDOLInitialize m_pfSDOLInitialize;
    LPSDOLGetModule m_pfSDOLGetModule;
    LPSDOLTerminal m_pfSDOLTerminal;

     m_pfSDOLInitialize = (LPSDOLInitialize)GetProcAddress(m_hSDOLoginModule, "SDOLInitialize");
    m_pfSDOLGetModule = (LPSDOLGetModule)GetProcAddress(m_hSDOLoginModule, "SDOLGetModule");
    m_pfSDOLTerminal = (LPSDOLTerminal)GetProcAddress(m_hSDOLoginModule, "SDOLTerminal");
    
    • 1
    • 2
    • 3

    代码解释:

    • 这段代码定义了三个函数指针类型的对象 m_pfSDOLInitializem_pfSDOLGetModulem_pfSDOLTerminal,分别用于指向动态链接库(DLL)中的函数 SDOLInitialize、SDOLGetModule 和 SDOLTerminal。

    • 然后,通过 GetProcAddress 函数,它尝试从 m_hSDOLoginModule 所代表的 DLL 中运行时候获取这三个函数的地址,并将这些地址分别赋值给 m_pfSDOLInitializem_pfSDOLGetModulem_pfSDOLTerminal,使得这些函数指针指向了对应的函数。

    • 这种方式允许你在运行时通过这些函数指针调用 DLL 中的函数,而不需要在编译时链接这些函数。这通常用于动态加载和调用 DLL 中的函数,以实现插件系统或模块化的应用程序架构。

    1、函数定义

    typedef int (WINAPI* LPSDOLInitialize)(const SDOLAppInfo* pAppInfo);
    typedef int (WINAPI* LPSDOLGetModule)(REFIID riid, void** intf);
    typedef int (WINAPI* LPSDOLTerminal)();
    
    • 1
    • 2
    • 3

    2、函数实现加载动态链接库

    bool Initial(){	
    	WCHAR strExePath[MAX_PATH] = { 0 };
    	WCHAR strExeName[MAX_PATH] = { 0 };
    	WCHAR* strLastSlash = NULL;
    	GetModuleFileNameW(NULL, strExePath, MAX_PATH);
    	strExePath[MAX_PATH - 1] = 0;
    	strLastSlash = wcsrchr(strExePath, TEXT('\\'));
    	if (strLastSlash)
    	{	// 得到EXE所在路径
    		StringCchCopyW(strExeName, MAX_PATH, &strLastSlash[1]);
    		*strLastSlash = 0;
    		strLastSlash = wcsrchr(strExeName, TEXT('.'));
    		if (strLastSlash)
    			*strLastSlash = 0;
    	}
    
    	WCHAR strGameWidgetDll[MAX_PATH] = { 0 };
    #ifdef _WIN64
    	StringCchPrintfW(strGameWidgetDll, MAX_PATH, L"%s\\sdo\\sdologinentry64.dll", strExePath);
    #else
    	StringCchPrintfW(strGameWidgetDll, MAX_PATH, L"%s\\sdo\\sdologinentry.dll", strExePath);
    #endif
    	if (GetFileAttributesW(strGameWidgetDll) == 0xFFFFFFFF) {
    		return false;
    	}
    //	string strEntry;
    //#ifdef _WIN64
    //	strEntry = PathHelper::GetFullPath("..\\sdologinentry64.dll");
    //#else
    //	strEntry = PathHelper::GetFullPath("..\\sdologinentry.dll");
    //#endif
        m_hSDOLoginModule = ::LoadLibraryW(strGameWidgetDll);
    	if (m_hSDOLoginModule == nullptr)
    	{
    		return false;
    	}
    	
    	//Out-of-game login interface
    	m_pfSDOLInitialize = (LPSDOLInitialize)GetProcAddress(m_hSDOLoginModule, "SDOLInitialize");
    	m_pfSDOLGetModule = (LPSDOLGetModule)GetProcAddress(m_hSDOLoginModule, "SDOLGetModule");
    	m_pfSDOLTerminal = (LPSDOLTerminal)GetProcAddress(m_hSDOLoginModule, "SDOLTerminal");
    
    	if (m_pfSDOLInitialize == nullptr || m_pfSDOLGetModule == nullptr) return false;
    SDOLAppInfo tmpAppInfo = {
    		sizeof(SDOLAppInfo),       // 结构体大小,方便扩展
    		appId,                 // 接入应用ID,从开发者网站中申请
    		L"游戏名称",     // 应用名称
    		L"0.1.2.0",            // 应用客户端当前版本号
    		1,                    // 游戏区ID,不可用时传入-1
    		1                     // 游戏组ID,不可用时传入-1
    	};
    
    	if (m_pfSDOLInitialize(&tmpAppInfo) == SDOL_ERRORCODE_OK)
    	{
    		m_pfSDOLGetModule(__uuidof(ISDOLLogin8), (void**)&m_pSDOLogin);
    		if (m_pSDOLogin == nullptr) return false;
    	}
    	else
    	{
    		return false;
    	}
    
    	m_pSDOLogin->SetLoginMode(LauncherLoginMode);
    	return CreateWorkerThread();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
      WCHAR strExePath[MAX_PATH] = { 0 };
    
    • 1

    WCHAR strExeName[MAX_PATH] = { 0 };
    WCHAR* strLastSlash = NULL;
    GetModuleFileNameW(NULL, strExePath, MAX_PATH);
    strExePath[MAX_PATH - 1] = 0;
    strLastSlash = wcsrchr(strExePath, TEXT(‘\’));
    if (strLastSlash)
    { // 得到EXE所在路径
    StringCchCopyW(strExeName, MAX_PATH, &strLastSlash[1]);
    *strLastSlash = 0;
    strLastSlash = wcsrchr(strExeName, TEXT(‘.’));
    if (strLastSlash)
    *strLastSlash = 0;
    }

    	WCHAR strGameWidgetDll[MAX_PATH] = { 0 };
    	#ifdef _WIN64
    		StringCchPrintfW(strGameWidgetDll, MAX_PATH, L"%s\\sdo\\sdologinentry64.dll", strExePath);
    	#else
    		StringCchPrintfW(strGameWidgetDll, MAX_PATH, L"%s\\sdo\\sdologinentry.dll", strExePath);
    	#endif
    		if (GetFileAttributesW(strGameWidgetDll) == 0xFFFFFFFF) {
    			return false;
    		}
    	//	string strEntry;
    	//#ifdef _WIN64
    	//	strEntry = PathHelper::GetFullPath("..\\sdologinentry64.dll");
    	//#else
    	//	strEntry = PathHelper::GetFullPath("..\\sdologinentry.dll");
    	//#endif
        m_hSDOLoginModule = ::LoadLibraryW(strGameWidgetDll);
    	if (m_hSDOLoginModule == nullptr)
    	{
    		return false;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    代码解释:

    • 获取当前执行程序的路径和名称:
      • 使用 GetModuleFileNameW 函数获取当前执行程序**(.exe)**的路径,并将其存储在 strExePath 中。
      • strExePath 中提取出执行程序的名称并存储在 strExeName 中。
    • 提取执行程序所在目录:
      • strExePath 中找到最后一个反斜杠 “” 的位置,然后将它替换为 NULL 终止字符以分隔目录路径和文件名。
      • 如果存在文件扩展名,也将其删除,以便获得纯粹的目录路径。
    • 根据当前架构构造 strGameWidgetDll 的路径:
      • 根据操作系统架构(32位或64位),构建 strGameWidgetDll 路径,这是一个包含了 “sdologinentry.dll” 或 “sdologinentry64.dll” 的完整路径。
    • 检查文件是否存在:
      • 使用 GetFileAttributesW 函数检查 strGameWidgetDll 文件是否存在,如果文件不存在,就返回 false
    • 加载动态链接库(DLL):
      • 使用 LoadLibraryW 函数加载 strGameWidgetDll 指定的 DLL 文件。如果加载失败,返回 false

    这段代码的目的是获取并加载一个特定的 DLL,该 DLL 位于与当前执行程序相同的目录下,根据操作系统架构选择加载 “sdologinentry.dll” 或 “sdologinentry64.dll”。如果加载成功,m_hSDOLoginModule 将包含该 DLL 的句柄,以便后续可以使用 GetProcAddress 来获取其中的函数地址。如果有任何错误发生,函数将返回 false

    m_pfSDOLInitialize = (LPSDOLInitialize)GetProcAddress(m_hSDOLoginModule, “SDOLInitialize”);

    代码解释:

    • m_pfSDOLInitialize 是一个函数指针,它似乎被用来指向一个函数,该函数的名称是 “SDOLInitialize”,并且这个函数是从模块 m_hSDOLoginModule 中获取的。这种情况通常用于动态链接库(Dynamic Link Library,DLL)或共享库中的函数调用。
    • 一般来说,这段代码的目的是将 m_pfSDOLInitialize 这个函数指针指向 m_hSDOLoginModule 模块中的 “SDOLInitialize” 函数,而m_hSDOLoginModule 模块是一个动态链接库中函数调用,以便后续可以通过该函数指针来调用 “SDOLInitialize” 函数,而不必直接链接到该函数的库。这种方式通常用于在运行时加载库并调用其中的函数,而不是在编译时链接到库。
    • 在使用 m_pfSDOLInitialize 这个函数指针之前,你需要确保 m_hSDOLoginModule 已经成功加载,并且 “SDOLInitialize” 函数已经在该模块中找到。否则,使用该函数指针可能导致运行时错误。

    m_pfSDOLGetModule = (LPSDOLGetModule)GetProcAddress(m_hSDOLoginModule, “SDOLGetModule”);

    代码解释:

    • 定义了一个函数指针 m_pfSDOLGetModule,并使用 GetProcAddress 函数从 m_hSDOLoginModule 模块中获取 “SDOLGetModule” 函数的地址,并将其分配给 m_pfSDOLGetModule。这意味着 m_pfSDOLGetModule 现在指向了 m_hSDOLoginModule 中的 “SDOLGetModule” 函数。
    • 这种操作通常用于动态加载函数,使你能够在运行时调用这些函数,而无需在编译时将其链接到代码中。 在使用 m_pfSDOLGetModule 指向的函数之前,你需要确保 m_hSDOLoginModule 已成功加载,并且 “SDOLGetModule” 函数确实存在于该模块中,否则会导致运行时错误。

    m_pfSDOLTerminal = (LPSDOLTerminal)GetProcAddress(m_hSDOLoginModule, “SDOLTerminal”);

    代码解释:

    • 定义了一个函数指针 m_pfSDOLTerminal,并使用 GetProcAddress 函数从 m_hSDOLoginModule 模块中获取 “SDOLTerminal” 函数的地址,并将其分配给 m_pfSDOLTerminal。这样,m_pfSDOLTerminal 现在指向了 m_hSDOLoginModule 中的 “SDOLTerminal” 函数。
    • 这种操作允许你在运行时动态加载并调用 “SDOLTerminal” 函数,而无需在编译时将其链接到代码中。 在使用 m_pfSDOLTerminal 指向的函数之前,确保 m_hSDOLoginModule 已成功加载,且 “SDOLTerminal” 函数确实存在于该模块中,以避免运行时错误。这样的方式通常用于插件系统或需要在运行时加载不同模块的应用程序。

    if (m_pfSDOLInitialize == nullptr || m_pfSDOLGetModule == nullptr) return false;

    代码解释:

    • 代码检查了 m_pfSDOLInitializem_pfSDOLGetModule 这两个函数指针是否为空指针(nullptr)。如果其中任何一个为空,它返回 false,否则继续执行后续的操作。
    • 这种检查通常用于确保成功加载并获取到所需的函数地址。如果在前面的 GetProcAddress 调用中,未能获取到 “SDOLInitialize” 或 “SDOLGetModule” 函数的地址,这些函数指针将会是空指针。因此,通过检查它们是否为空,你可以在继续使用这些函数指针之前确保它们已成功获取,以避免在尝试调用这些函数时引发未定义行为或错误。
    • 这是一种常见的做法,用于提高代码的鲁棒性,特别是在涉及动态加载函数的情况下。如果函数指针不为空,那么它们将指向有效的函数,否则你可以选择采取适当的错误处理措施。

    3、sdologinentry.dll或者sdologinentry64.dll动态链接库哪个工程生成的并导出三个接口函数

    很明显由updatecore工程生成的sdologinentry.dllsdologinentry64.dll的动态链接库。
    在这里插入图片描述

    int WINAPI SDOLInitialize(const SDOLAppInfo* pAppInfo)
    {
    	TCHAR path[32768*2] = {0};
    	DWORD len = GetEnvironmentVariable(_T("PATH"), path, _countof(path));
    
    	TCHAR buffer[MAX_PATH] = {0};
    	GetModuleFileName(g_hModule, buffer, _countof(buffer));
    
    	_stprintf(path+len, _T(";%s\\..\\sdologin\\"), buffer);
    
    	SetEnvironmentVariable(_T("PATH"), path);
    
    	SDOLAppInfo* pInfo = (SDOLAppInfo*)pAppInfo;
    
    	// Skip update process or not
    	wchar_t buffer2[MAX_PATH] = {0};
    	wchar_t path2[MAX_PATH*2] = {0};
    	GetModuleFileNameW(g_hModule, buffer2, _countof(buffer2));
    	swprintf_s(path2, _countof(path2), L"%s\\..\\sdologin\\", buffer2);
    
    	LicenseManager::Initial(path2);
    	bool bExpired = LicenseManager::GetInstance()->GetValue("Expiration");
    	bool bSkipUpdate = LicenseManager::GetInstance()->GetValue("SkipUpdate");
    
    	if (!(bExpired == false && bSkipUpdate == true)) // !(未过期 && 跳过更新)
    	{
    		if (Update::GetInstance()->CheckLocalVersion())
    		{
    			if(!Update::GetInstance()->DownloadUpdate(pInfo->AppID, pInfo->AreaId, pInfo->GroupId))
    			{
    				return SDOA_FALSE;
    			}
    		}
    		else
    		{
    			if (!Update::GetInstance()->ForceUpdate(pInfo->AppID, pInfo->AreaId, pInfo->GroupId))
    			{
    				return SDOA_FALSE;
    			}
    		}
    	}
    
    /*
    #ifdef _WIN64
    	g_hSdoLogin = LoadLibrary(_T("sdologinsdk64.dll"));
    #else
    	g_hSdoLogin = LoadLibrary(_T("sdologinsdk.dll"));
    #endif
    */
    
    	GetModuleFileName(g_hModule, buffer, _countof(buffer));
    
    #ifdef _WIN64
    	sprintf(buffer + strlen(buffer) - strlen("sdologinentry64.dll"), "sdologin\\sdologinsdk64.dll");
    #else
    	sprintf(buffer + strlen(buffer) - strlen("sdologinentry.dll"), "sdologin\\sdologinsdk.dll");
    #endif
    
    	g_hSdoLogin = LoadLibraryEx(buffer, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
    
    	LPSDOLInitialize pFun = (LPSDOLInitialize)GetProcAddress(g_hSdoLogin, "SDOLInitialize");
    	if(pFun)
    	{
    		return pFun(pAppInfo);
    	}
    	return SDOA_FALSE;
    }
    
    int WINAPI SDOLGetModule(REFIID riid, void** intf)
    {
    	LPSDOLGetModule pFun = (LPSDOLGetModule)GetProcAddress(g_hSdoLogin, "SDOLGetModule");
    	if(pFun)
    	{
    		return pFun(riid, intf);
    	}
    	return false;
    }
    
    int WINAPI SDOLTerminal()
    {
    	LPSDOLTerminal pFun = (LPSDOLTerminal)GetProcAddress(g_hSdoLogin, "SDOLTerminal");
    	int ret = SDOA_FALSE;
    	if(pFun)
    	{
    		ret = pFun();
    	}
    
    	FreeLibrary(g_hSdoLogin);
    
    	if(ret == SDOL_ERRORCODE_OK)
    	{
    		Update::GetInstance()->SetupUpdate();
    	}
    	Update::Destroy();
    
    	return ret;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97

    int WINAPI SDOLInitialize(const SDOLAppInfo* pAppInfo)

    {

    ​ TCHAR path[32768*2] = {0};
    ​ DWORD len = GetEnvironmentVariable(_T(“PATH”), path, _countof(path));

    ​ TCHAR buffer[MAX_PATH] = {0};
    ​ GetModuleFileName(g_hModule, buffer, _countof(buffer));

    ​ _stprintf(path+len, _T(“;%s\…\sdologin\”), buffer);

    ​ SetEnvironmentVariable(_T(“PATH”), path);

    ​ SDOLAppInfo* pInfo = (SDOLAppInfo*)pAppInfo;

    ​ SetEnvironmentVariable(_T(“PATH”), path);

    ​ SDOLAppInfo* pInfo = (SDOLAppInfo*)pAppInfo;

    ​ // Skip update process or not
    ​ wchar_t buffer2[MAX_PATH] = {0};
    ​ wchar_t path2[MAX_PATH*2] = {0};
    ​ GetModuleFileNameW(g_hModule, buffer2, _countof(buffer2));
    ​ swprintf_s(path2, _countof(path2), L"%s\…\sdologin\", buffer2);

    ​ LicenseManager::Initial(path2);
    ​ bool bExpired = LicenseManager::GetInstance()->GetValue(“Expiration”);
    ​ bool bSkipUpdate = LicenseManager::GetInstance()->GetValue(“SkipUpdate”);

    ​ if (!(bExpired == false && bSkipUpdate == true)) // !(未过期 && 跳过更新)
    ​ {
    ​ if (Update::GetInstance()->CheckLocalVersion())
    ​ {
    ​ if(!Update::GetInstance()->DownloadUpdate(pInfo->AppID, pInfo->AreaId, pInfo->GroupId))
    ​ {
    ​ return SDOA_FALSE;
    ​ }
    ​ }
    ​ else
    ​ {
    ​ if (!Update::GetInstance()->ForceUpdate(pInfo->AppID, pInfo->AreaId, pInfo->GroupId))
    ​ {
    ​ return SDOA_FALSE;
    ​ }
    ​ }
    ​ }

    /*
    #ifdef _WIN64
    g_hSdoLogin = LoadLibrary(_T(“sdologinsdk64.dll”));
    #else
    g_hSdoLogin = LoadLibrary(_T(“sdologinsdk.dll”));
    #endif
    */

    ​ GetModuleFileName(g_hModule, buffer, _countof(buffer));

    #ifdef _WIN64
    sprintf(buffer + strlen(buffer) - strlen(“sdologinentry64.dll”), “sdologin\sdologinsdk64.dll”);
    #else
    sprintf(buffer + strlen(buffer) - strlen(“sdologinentry.dll”), “sdologin\sdologinsdk.dll”);
    #endif

    ​ g_hSdoLogin = LoadLibraryEx(buffer, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);

    ​ LPSDOLInitialize pFun = (LPSDOLInitialize)GetProcAddress(g_hSdoLogin, “SDOLInitialize”);
    ​ if(pFun)
    ​ {
    ​ return pFun(pAppInfo);
    ​ }
    ​ return SDOA_FALSE;

    }

    代码解释:

    • 这段代码是一个函数 SDOLInitialize 的实现,以下是它的主要功能:
      1. 获取当前环境变量中的 PATH,并向其中添加一个目录路径。这个目录路径是 sdologin 目录,它相对于当前执行程序的目录。
      2. 初始化 LicenseManager,它的目的是获取和检查许可证信息。
      3. 检查许可证信息中的 “Expiration” 和 “SkipUpdate” 值,根据这些值决定是否跳过更新过程。
      4. 如果不跳过更新,检查本地版本并尝试下载或强制更新。
      5. 最后,通过构建动态链接库文件路径,加载 sdologinsdk.dllsdologinsdk64.dll(取决于系统架构),同理并调用动态链接库中的 SDOLInitialize 函数。
    • 总体来说,这段代码的功能是在初始化时检查许可证信息,决定是否需要进行更新,并加载相应的动态链接库以继续应用程序的初始化过程。根据许可证信息,它可能跳过更新或执行更新操作。这种方式通常用于软件的自动更新或版本管理。

    int WINAPI SDOLGetModule(REFIID riid, void** intf)
    {
    LPSDOLGetModule pFun = (LPSDOLGetModule)GetProcAddress(g_hSdoLogin, “SDOLGetModule”);
    if(pFun)
    {
    return pFun(riid, intf);
    }
    return false;
    }

    代码解释:

    • 这段代码是一个函数 SDOLGetModule 的实现,以下是它的主要功能:
      1. 首先,它通过 GetProcAddress 函数尝试从同理并调用动态链接库中的加载的 g_hSdoLogin 动态链接库中获取名为 “SDOLGetModule” 的函数的地址,这个函数似乎是一个用于获取模块的接口(COM 接口)的函数。
      2. 如果成功获取到该函数的地址,它调用该函数,并将 riidintf 参数传递给它。
      3. 如果获取和调用都成功,函数返回从 pFun 调用的结果。
      4. 如果无法获取到该函数的地址,或者获取和调用失败,函数返回 false
    • 这段代码似乎是为了实现动态加载的模块系统,其中 SDOLGetModule 函数用于获取指定接口的模块。如果成功获取到并调用了模块中的 SDOLGetModule 函数,它将返回相应的结果,否则返回 false 表示失败。通常,这种方式用于插件系统或模块化的应用程序,可以在运行时加载不同的模块并获取它们的接口。

    int WINAPI SDOLTerminal()
    {
    LPSDOLTerminal pFun = (LPSDOLTerminal)GetProcAddress(g_hSdoLogin, “SDOLTerminal”);
    int ret = SDOA_FALSE;
    if(pFun)
    {
    ret = pFun();
    }

    ​ FreeLibrary(g_hSdoLogin);

    ​ if(ret == SDOL_ERRORCODE_OK)
    ​ {
    ​ Update::GetInstance()->SetupUpdate();
    ​ }
    ​ Update::Destroy();

    ​ return ret;

    }

    代码解释:

    • 这段代码是一个函数 SDOLTerminal 的实现,以下是它的主要功能:

      1. 首先,它通过 GetProcAddress 函数尝试从同理并调用动态链接库中的加载的 g_hSdoLogin 动态链接库中获取名为 “SDOLTerminal” 的函数的地址,似乎是一个用于终止模块操作的函数。
      2. 如果成功获取到该函数的地址,它调用该函数,并将返回的结果存储在 ret 变量中。
      3. 接着,它使用 FreeLibrary 函数释放 g_hSdoLogin 动态链接库,即卸载模块。
      4. 如果 ret 的值等于 SDOL_ERRORCODE_OK,则表示成功执行模块操作,它会调用 Update::GetInstance()->SetupUpdate() 来设置更新,否则跳过这一步。
      5. 最后,它调用 Update::Destroy() 来释放更新相关的资源,并返回 ret 的值。
    • 这段代码的主要作用是在模块操作结束时,执行一些清理工作,包括释放动态链接库,进行更新设置,以及资源的销毁。这通常用于模块的初始化和终止过程。

    解释如何调用到sdologinentry.dll或者sdologinentry64.dll库中的三个函数:

    SDOLInitialize

    SDOLGetModule

    SDOLTerminal

    LIBRARY	"updatecore"
    
    EXPORTS
    	igwInitialize
    	igwGetModule
    	igwTerminal
    	SDOLInitialize
    	SDOLGetModule
    	SDOLTerminal
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    资源解释:

    • 这是一个动态链接库(DLL)的导出符号定义部分。在这个定义中:
      • LIBRARY "updatecore" 表示该动态链接库的名称为 “updatecore”。
      • EXPORTS 下面列出了一系列函数名称,它们将会在该 DLL 中被导出,以便其他模块或程序可以调用这些函数。这些函数包括了 igwInitializeigwGetModuleigwTerminalSDOLInitializeSDOLGetModule 以及 SDOLTerminal
    • 这些导出函数通常是其他程序或模块需要使用的接口。通过将它们导出,其他程序可以通过动态链接的方式加载这个 DLL,并使用这些函数来执行特定的操作。在你之前提供的代码中,通过 GetProcAddress 函数来获取并调用这些函数,这使得你可以在运行时动态加载和使用这些功能。

    4、sdologinsdk.dll或者sdologinsdk64.dll动态链接库哪个工程生成并导出三个接口函数

    SDOLInitialize

    SDOLGetModule

    SDOLTerminal

    很明显由sdk工程生成的sdologinsdk.dllsdologinsdk64.dll的动态链接库。

    在这里插入图片描述

    static SDOLLogin* g_pSDOLLogin = NULL;
    static SDOLInfo*  g_pSDOLInfo = NULL;
    bool _SDOLGetModule(REFIID riid, void** intf);
    bool _igwGetModule(REFIID riid, void** intf);
    
    int WINAPI SDOLInitializeInternal(const SDOLAppInfo* pAppInfo)
    {
    	TRACET();
    	TRACEI(_T("pAppInfo[0x%x]\n"), pAppInfo);
    
    	if(pAppInfo == NULL || pAppInfo->Size != sizeof(SDOLAppInfo))
    	{
    		TRACEW("SDOLII pAppInfo error.");
    		return SDOL_ERRORCODE_INVALIDPARAM;
    	}
    
    	if(!ModuleLoginSDK::Initial(pAppInfo))
    	{
    		TRACEW("ModuleLoginSDK::Initial() failed.");
    		return SDOL_ERRORCODE_FAILED;
    	}
    
    	TRACEI(_T("AppID[%d] AppName[%s] AppVer[%s] AreaId[%d] GroupId[%d]\n"), 
    		pAppInfo->AppID, pAppInfo->AppName, pAppInfo->AppVer, pAppInfo->AreaId, pAppInfo->GroupId);
    
    	//ModuleLoginSDK::GetInstance()->SetAppInfo(pAppInfo);
    
    	g_pSDOLLogin = new SDOLLogin();
    	g_pSDOLInfo = new SDOLInfo();
    
    	return SDOL_ERRORCODE_OK;
    };
    
    
    bool _InitObjects( const SDOLAppInfo& appInfo ) ;
    int WINAPI SDOLInitialize(const SDOLAppInfo* pAppInfo)
    {
    	TRACET();
    	TRACEI(_T("pAppInfo[0x%x]\n"), pAppInfo);
    	if (NULL != pAppInfo)
    	{
    		TRACEI(_T("pAppInfo->Size[%d]\n"), pAppInfo->Size);
    		TRACEI(_T("pAppInfo->AppID[%d]\n"), pAppInfo->AppID);
    		TRACEI(_T("pAppInfo->AppName[%s]\n"), pAppInfo->AppName);
    		TRACEI(_T("pAppInfo->AppVer[%s]\n"), pAppInfo->AppVer);
    		TRACEI(_T("pAppInfo->AreaId[%d]\n"), pAppInfo->AreaId);
    	}
    
    	// zlc bool res = _InitObjects(*pAppInfo);
    	SDOLAppInfo struAppInfo;
    	memcpy(&struAppInfo, pAppInfo, sizeof(SDOLAppInfo));
    	if (struAppInfo.AppID == 0)
    		struAppInfo.AppID = 791000388; //zlc here
    	bool res = _InitObjects(struAppInfo);
    	if (!res)
    	{
    		return SDOL_ERRORCODE_FAILED;
    	}
    
    	ModuleLoginSDK::GetInstance()->SetWindowMode(SetWindowModeReq::OutsideGame);
    
    	return SDOL_ERRORCODE_OK;
    };
    
    
    
    int WINAPI SDOLGetModule(REFIID riid, void** intf)
    {
    	TRACET();
    
    	OLECHAR* guid = NULL; 
    	StringFromIID(riid, &guid);
    	TRACEI(_T("0 SDOLGetModule riid[%s]"), guid);
    
    	bool res = false;
    	res = _SDOLGetModule(riid, intf);
    	if (!res)
    	{
    		res = _igwGetModule(riid, intf);
    	}
    
    	if (res)
    	{
    		OLECHAR* guid = NULL; 
    		StringFromIID(riid, &guid);
    		TRACEI(_T("1 SDOLGetModule riid[%s]"), guid);
    	}	
    
    	return res ? SDOL_ERRORCODE_OK:SDOL_ERRORCODE_FAILED;
    };
    
    int WINAPI SDOLTerminal()
    {
    	TRACET();
    	TRACEI(_T(""));
    
    	int ret = ModuleLoginSDK::Destroy();
    
    	SAFE_DELETE(g_pSDOLLogin);
    
    	return ret == ShutdownSuccess ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
    };
    
    bool _SDOLGetModule(REFIID riid, void** intf)
    {
    	TRACET();
    	TRACEI(_T(""));
    
    	if(riid == __uuidof(ISDOLLogin))
    	{
    		*intf = (void*)(ISDOLLogin*)g_pSDOLLogin;
    		return true;
    	}
    	if(riid == __uuidof(ISDOLLogin2))
    	{
    		*intf = (void*)(ISDOLLogin2*)g_pSDOLLogin;
    		return true;
    	}
    	if (riid == __uuidof(ISDOLInfo))
    	{
    		*intf = (void*)(ISDOLInfo*)g_pSDOLInfo;
    		return true;
    	}
    	if(riid == __uuidof(ISDOLLogin3))
    	{
    		*intf = (void*)(ISDOLLogin3*)g_pSDOLLogin;
    		return true;
    	}
    	if(riid == __uuidof(ISDOLLogin4))
    	{
    		*intf = (void*)(ISDOLLogin4*)g_pSDOLLogin;
    		return true;
    	}
    	if(riid == __uuidof(ISDOLLogin5))
    	{
    		*intf = (void*)(ISDOLLogin5*)g_pSDOLLogin;
    		return true;
    	}
    	if(riid == __uuidof(ISDOLLogin6))
    	{
    		*intf = (void*)(ISDOLLogin6*)g_pSDOLLogin;
    		return true;
    	}
    	if(riid == __uuidof(ISDOLLogin7))
    	{
    		*intf = (void*)(ISDOLLogin7*)g_pSDOLLogin;
    		return true;
    	}
    	if(riid == __uuidof(ISDOLLogin8))
    	{
    		*intf = (void*)(ISDOLLogin8*)g_pSDOLLogin;
    		return true;
    	}
    
    	return false;
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157

    static SDOLLogin* g_pSDOLLogin = NULL;
    static SDOLInfo* g_pSDOLInfo = NULL;
    bool _SDOLGetModule(REFIID riid, void** intf);
    bool _igwGetModule(REFIID riid, void** intf);

    int WINAPI SDOLInitializeInternal(const SDOLAppInfo* pAppInfo)
    {
    TRACET();
    TRACEI(_T(“pAppInfo[0x%x]\n”), pAppInfo);

    ​ if(pAppInfo == NULL || pAppInfo->Size != sizeof(SDOLAppInfo))
    ​ {
    ​ TRACEW(“SDOLII pAppInfo error.”);
    ​ return SDOL_ERRORCODE_INVALIDPARAM;
    ​ }

    ​ if(!ModuleLoginSDK::Initial(pAppInfo))
    ​ {
    ​ TRACEW(“ModuleLoginSDK::Initial() failed.”);
    ​ return SDOL_ERRORCODE_FAILED;
    ​ }

    ​ TRACEI(_T(“AppID[%d] AppName[%s] AppVer[%s] AreaId[%d] GroupId[%d]\n”),
    ​ pAppInfo->AppID, pAppInfo->AppName, pAppInfo->AppVer, pAppInfo->AreaId, pAppInfo->GroupId);

    ​ //ModuleLoginSDK::GetInstance()->SetAppInfo(pAppInfo);

    ​ g_pSDOLLogin = new SDOLLogin();
    ​ g_pSDOLInfo = new SDOLInfo();

    ​ return SDOL_ERRORCODE_OK;

    };

    代码解释:

    • 这段代码定义了一个名为 SDOLInitializeInternal 的函数,以下是它的主要功能:

      1. 在函数开始时,通过 TRACEI 函数和 TRACEW 函数输出一些信息,用于调试和日志记录。
      2. 首先,它检查传入的 pAppInfo 参数是否为 NULL 或其大小是否与 sizeof(SDOLAppInfo) 相符。如果不符合条件,函数会返回 SDOL_ERRORCODE_INVALIDPARAM 表示参数无效。
      3. 接着,如果上述检查通过,它调用 ModuleLoginSDK::Initial(pAppInfo) 函数,尝试进行一些初始化操作。如果初始化失败,函数返回 SDOL_ERRORCODE_FAILED 表示初始化失败。
      4. 如果初始化成功,它继续输出 pAppInfo 中的一些信息,包括了 AppIDAppNameAppVerAreaIdGroupId
      5. 然后,它创建了两个对象:g_pSDOLLoging_pSDOLInfo,分别是 SDOLLoginSDOLInfo 的实例。
      6. 最后,函数返回 SDOL_ERRORCODE_OK 表示初始化成功。
    • 这段代码的主要目的是在应用程序的初始化过程中,根据传入的应用信息进行一些初始化工作,包括了调用 ModuleLoginSDK::Initial 函数,创建 SDOLLoginSDOLInfo 的对象。如果初始化成功,函数返回成功状态码,否则返回失败状态码。

    bool InitObjects( const SDOLAppInfo& appInfo ) ;
    bool _InitObjects( const SDOLAppInfo& appInfo )
    {
    TRACET();
    ​ if(SDOLInitializeInternal(&appInfo) != SDOL_ERRORCODE_OK)
    ​ {
    ​ return false;
    ​ }
    ​ // if(g_pSDOAApp2 == NULL)
    ​ // {
    ​ // g_pSDOAApp2 = new SDOAApp2();
    ​ // }
    ​ if(g_pSDOAApp4 == NULL)
    ​ {
    ​ g_pSDOAApp4 = new SDOAApp4();
    ​ }
    ​ if(g_pSDOAAppEx == NULL)
    ​ {
    ​ g_pSDOAAppEx = new IGW2::SDOAAppEx();
    ​ }
    ​ if(g_pSDOAAppUtils == NULL)
    ​ {
    ​ g_pSDOAAppUtils = new SDOAAppUtils();
    ​ }
    ​ if(g_pSDOAClientService == NULL)
    ​ {
    ​ g_pSDOAClientService = new SDOAClientService();
    ​ }
    return true;
    }

    代码解释:

    • 这段代码定义了一个名为 _InitObjects 的函数,以下是它的主要功能:
      1. 在函数开始时,通过 TRACE 函数输出一些信息,用于调试和日志记录。
      2. 接着,它调用 SDOLInitializeInternal(&appInfo) 函数,尝试进行一些初始化操作。如果 SDOLInitializeInternal 返回的值不等于 SDOL_ERRORCODE_OK,表示初始化失败,函数返回 false 表示初始化对象失败。
      3. 然后,它检查一系列全局指针(g_pSDOAApp4g_pSDOAAppExg_pSDOAAppUtilsg_pSDOAClientService),如果其中有任何一个指针为空,它将分别创建对应的对象实例,这些对象可能是特定的应用程序对象。
      4. 最后,如果上述初始化和对象创建都成功,函数返回 true 表示初始化对象成功。
    • 这段代码的主要目的是在应用程序初始化过程中,进行一些对象的初始化和创建工作,包括了调用 SDOLInitializeInternal 函数,通过这个函数调用到SDK中的初始化函数,以及创建特定的应用程序对象。如果初始化对象成功,函数返回 true,否则返回 false。这些对象通常用于应用程序的功能实现和操作。

    bool _InitObjects( const SDOLAppInfo& appInfo ) ;
    int WINAPI SDOLInitialize(const SDOLAppInfo* pAppInfo)
    {
    TRACET();
    TRACEI(_T(“pAppInfo[0x%x]\n”), pAppInfo);
    if (NULL != pAppInfo)
    {
    TRACEI(_T(“pAppInfo->Size[%d]\n”), pAppInfo->Size);
    TRACEI(_T(“pAppInfo->AppID[%d]\n”), pAppInfo->AppID);
    TRACEI(_T(“pAppInfo->AppName[%s]\n”), pAppInfo->AppName);
    TRACEI(_T(“pAppInfo->AppVer[%s]\n”), pAppInfo->AppVer);
    TRACEI(_T(“pAppInfo->AreaId[%d]\n”), pAppInfo->AreaId);
    }

    ​ // zlc bool res = _InitObjects(*pAppInfo);
    ​ SDOLAppInfo struAppInfo;
    ​ memcpy(&struAppInfo, pAppInfo, sizeof(SDOLAppInfo));
    ​ if (struAppInfo.AppID == 0)
    ​ struAppInfo.AppID = 791000388; //zlc here
    ​ bool res = _InitObjects(struAppInfo);
    ​ if (!res)
    ​ {
    ​ return SDOL_ERRORCODE_FAILED;
    ​ }

    ​ ModuleLoginSDK::GetInstance()->SetWindowMode(SetWindowModeReq::OutsideGame);

    ​ return SDOL_ERRORCODE_OK;

    };

    代码解释:

    • 这段代码是一个名为 SDOLInitialize 的函数的实现,以下是它的主要功能:

      1. 在函数开始时,通过一系列 TRACEI 函数调用来输出一些信息,这些信息包括了 pAppInfo 参数的各个成员的值,以便进行调试和日志记录。
      2. 接着,它创建一个名为 struAppInfo 的局部变量,并通过 memcpy 函数将 pAppInfo 的内容复制到 struAppInfo 中。然后,它检查 struAppInfo 中的 AppID 是否为 0,如果是,将其设置为 791000388。
      3. 接下来,它调用 _InitObjects 函数,将 struAppInfo 作为参数传递给它。_InitObjects 函数可能用于初始化一些对象或资源,这部分的具体逻辑在 _InitObjects 函数中实现。
      4. 如果 _InitObjects 返回 true 表示初始化成功,它将调用 ModuleLoginSDK::GetInstance()->SetWindowMode(SetWindowModeReq::OutsideGame) 来设置某种窗口模式。窗口模式的设置可能与应用程序的显示方式有关。
      5. 最后,如果初始化成功,函数返回 SDOL_ERRORCODE_OK,否则返回 SDOL_ERRORCODE_FAILED 表示初始化失败。
    • 总的来说,这段代码的目的是在应用程序初始化过程中,根据传入的应用信息进行一些初始化工作,包括了调用 _InitObjects 函数和设置窗口模式。如果初始化成功,返回成功状态码,否则返回失败状态码。

    int WINAPI SDOLGetModule(REFIID riid, void** intf)
    {
    TRACET();

    ​ OLECHAR* guid = NULL;
    ​ StringFromIID(riid, &guid);
    ​ TRACEI(_T(“0 SDOLGetModule riid[%s]”), guid);

    ​ bool res = false;
    ​ res = _SDOLGetModule(riid, intf);
    ​ if (!res)
    ​ {
    ​ res = _igwGetModule(riid, intf);
    ​ }

    ​ if (res)
    ​ {
    ​ OLECHAR* guid = NULL;
    ​ StringFromIID(riid, &guid);
    ​ TRACEI(_T(“1 SDOLGetModule riid[%s]”), guid);
    ​ }

    ​ return res ? SDOL_ERRORCODE_OK:SDOL_ERRORCODE_FAILED;

    };

    代码解释:

    • 这段代码是一个名为 SDOLGetModule 的函数的实现,以下是它的主要功能:
      1. 在函数开始时,通过 TRACEI 函数和 StringFromIID 函数输出一些信息,包括 riid 参数的 GUID。
      2. 接着,它创建一个名为 guid 的指针,并通过 StringFromIID 函数将 riid 转换为字符串形式,并将结果存储在 guid 中。
      3. 然后,它调用 _SDOLGetModule 函数,传递 riidintf 作为参数,以尝试获取模块。
      4. 如果 _SDOLGetModule 返回 false(表示获取模块失败),它接着调用 _igwGetModule 函数,再次尝试获取模块。
      5. 如果成功获取到模块,它再次输出 riid 的信息,然后返回 SDOL_ERRORCODE_OK 表示成功。
      6. 如果两次尝试都没有成功获取模块,它最终返回 SDOL_ERRORCODE_FAILED 表示失败。
    • 总的来说,这段代码的目的是尝试获取一个模块,首先通过 _SDOLGetModule 尝试,如果失败再通过 _igwGetModule 尝试。如果成功获取到模块,它返回成功状态码,否则返回失败状态码。

    int WINAPI SDOLTerminal()
    {
    TRACET();
    TRACEI(_T(“”));

    ​ int ret = ModuleLoginSDK::Destroy();

    ​ SAFE_DELETE(g_pSDOLLogin);

    ​ return ret == ShutdownSuccess ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;

    }

    代码解释:

    • 这段代码是一个名为 SDOLTerminal 的函数的实现,以下是它的主要功能:
      1. 在函数开始时,通过 TRACEI 函数输出一些信息,用于调试和日志记录。
      2. 接着,它调用 ModuleLoginSDK::Destroy() 函数,该函数可能用于销毁一些模块相关的资源和对象。
      3. ModuleLoginSDK::Destroy() 返回的结果存储在 ret 变量中,这个结果可能是一个表示销毁操作是否成功的值。
      4. 然后,它通过 SAFE_DELETE(g_pSDOLLogin) 来释放 g_pSDOLLogin 所指向的对象或资源。这个宏可能用于安全地删除指针,并将指针置为 nullptr
      5. 最后,如果 ret 的值等于 ShutdownSuccess,它返回 SDOL_ERRORCODE_OK 表示终止成功,否则返回 SDOL_ERRORCODE_FAILED 表示终止失败。
    • 这段代码的主要目的是在应用程序终止时执行一些清理操作,包括销毁模块相关的资源和对象,然后返回适当的状态码以表示终止的结果。

    bool _SDOLGetModule(REFIID riid, void** intf)
    {
    TRACET();
    TRACEI(_T(“”));

    ​ if(riid == __uuidof(ISDOLLogin))
    ​ {
    intf = (void)(ISDOLLogin*)g_pSDOLLogin;
    ​ return true;
    ​ }
    ​ if(riid == __uuidof(ISDOLLogin2))
    ​ {
    intf = (void)(ISDOLLogin2*)g_pSDOLLogin;
    ​ return true;
    ​ }
    ​ if (riid == __uuidof(ISDOLInfo))
    ​ {
    intf = (void)(ISDOLInfo*)g_pSDOLInfo;
    ​ return true;
    ​ }
    ​ if(riid == __uuidof(ISDOLLogin3))
    ​ {
    intf = (void)(ISDOLLogin3*)g_pSDOLLogin;
    ​ return true;
    ​ }
    ​ if(riid == __uuidof(ISDOLLogin4))
    ​ {
    intf = (void)(ISDOLLogin4*)g_pSDOLLogin;
    ​ return true;
    ​ }
    ​ if(riid == __uuidof(ISDOLLogin5))
    ​ {
    intf = (void)(ISDOLLogin5*)g_pSDOLLogin;
    ​ return true;
    ​ }
    ​ if(riid == __uuidof(ISDOLLogin6))
    ​ {
    intf = (void)(ISDOLLogin6*)g_pSDOLLogin;
    ​ return true;
    ​ }
    ​ if(riid == __uuidof(ISDOLLogin7))
    ​ {
    intf = (void)(ISDOLLogin7*)g_pSDOLLogin;
    ​ return true;
    ​ }
    ​ if(riid == __uuidof(ISDOLLogin8))
    ​ {
    intf = (void)(ISDOLLogin8*)g_pSDOLLogin;
    ​ return true;
    ​ }

    ​ return false;

    };

    代码解释:

    • 这段代码是一个名为 _SDOLGetModule 的函数的实现,以下是它的主要功能:
      1. 在函数开始时,通过 TRACEI 函数输出一些信息,用于调试和日志记录。
      2. 然后,它检查传入的 riid 参数是否等于特定的接口类型的 UUID(GUID)。如果 riid 匹配某个特定接口类型的 UUID,它将将 *intf 指向相应的接口指针,并返回 true 表示成功。
      3. 如果 riid 不匹配任何已知的接口类型,它返回 false 表示失败。
    • 这段代码的主要目的是根据传入的 riid 参数,尝试获取对应的接口,并将接口指针存储在 *intf 中,以便其他部分的代码可以使用这些接口进行操作。如果 riid 匹配已知接口类型,则返回 true,否则返回 false。这通常用于实现 COM 接口的获取和对象的实例化。

    bool _igwGetModule(REFIID riid, void** intf)
    {
    if(riid == __uuidof(ISDOAApp))
    {
    intf = (void)(ISDOAApp*)g_pSDOAApp4;
    return true;
    }
    if(riid == __uuidof(ISDOAApp2))
    {
    intf = (void)(ISDOAApp2*)g_pSDOAApp4;
    return true;
    }
    if(riid == __uuidof(ISDOAApp3))
    {
    intf = (void)(ISDOAApp3*)g_pSDOAApp4;
    return true;
    }
    if(riid == __uuidof(ISDOAApp4))
    {
    intf = (void)(ISDOAApp4*)g_pSDOAApp4;
    return true;
    }
    if(riid == __uuidof(IGW2::ISDOAAppEx))
    {
    intf = (void)(IGW2::ISDOAAppEx*)g_pSDOAAppEx;
    return true;
    }
    if(riid == __uuidof(ISDOAAppUtils))
    {
    intf = (void)(ISDOAAppUtils*)g_pSDOAAppUtils;
    return true;
    }
    if(riid == __uuidof(ISDOAClientService))
    {
    intf = (void)(ISDOAClientService*)g_pSDOAClientService;
    return true;
    }

    ​ if(riid == __uuidof(IGPLUSApp))
    ​ {
    intf = (void)(IGPLUSApp*)CGPlusManager::GetInstance()->getGplusAppObject();
    ​ return true;
    ​ }

    ​ //if(Dx7GetModule(riid, intf))
    ​ //{
    ​ // return true;
    ​ //}
    ​ if(Dx8GetModule(riid, intf))
    ​ {
    ​ return true;
    ​ }
    ​ if(Dx9GetModule(riid, intf))
    ​ {
    ​ return true;
    ​ }
    ​ if(Dx11GetModule(riid, intf))
    ​ {
    ​ return true;
    ​ }
    ​ if(GDIGetModule(riid, intf))
    ​ {
    ​ return true;
    ​ }
    ​ if(DDrawGetModule(riid, intf))
    ​ {
    ​ return true;
    ​ }
    ​ return false;

    }

    代码解释:

    • 这段代码是一个名为 _igwGetModule 的函数的实现,以下是它的主要功能:

      1. 它检查传入的 riid 参数是否等于特定的接口类型的 UUID(GUID)。如果 riid 匹配某个特定接口类型的 UUID,它将将 *intf 指向相应的接口指针,并返回 true 表示成功。
      2. 如果 riid 不匹配已知的接口类型,它继续检查其他接口类型,包括 Dx8GetModuleDx9GetModuleDx11GetModuleGDIGetModuleDDrawGetModule 等。如果传入的 riid 匹配这些接口类型中的任何一个,它同样将 *intf 指向相应的接口指针,并返回 true 表示成功。
      3. 如果所有的检查都失败,它最终返回 false 表示没有匹配的接口。
    • 这段代码的主要目的是根据传入的 riid 参数,尝试获取对应的接口,并将接口指针存储在 *intf 中,以便其他部分的代码可以使用这些接口进行操作。这是一种通用的接口获取机制,用于获取不同接口类型的对象。如果 riid 匹配已知的接口类型,它返回 true,否则返回 false。这通常用于实现 COM 接口的获取和对象的实例化。

    解释如何调用到sdologinsdk.dll或者sdologinsdk64.dll库中的三个函数:

    LIBRARY “sdologinsdk”

    EXPORTS
    SDOLInitialize
    SDOLGetModule
    SDOLTerminal
    igwInitialize
    igwGetModule
    igwTerminal

    代码解释:

    • 这段代码定义了一个名为 “sdologinsdk” 的动态链接库(DLL)的导出符号,它列出了一系列函数名称,这些函数将会在该 DLL 中被导出,以便其他模块或程序可以通过动态链接的方式调用这些函数。导出的函数包括了:
      1. SDOLInitialize
      2. SDOLGetModule
      3. SDOLTerminal
      4. igwInitialize
      5. igwGetModule
      6. igwTerminal
    • 这些导出函数通常是其他程序或模块需要使用的接口。通过将它们导出,其他程序可以在运行时动态加载这个 DLL,并使用这些函数来执行特定的操作。这种方式通常用于插件系统或模块化的应用程序,允许不同的模块或插件在运行时添加到应用程序中,以扩展其功能。
  • 相关阅读:
    mysql使用orderby 不起作用
    Nginx自签名证书的配置
    Linux下jar包的运行、查看、终止
    工业生产中废酸回收技术的原理分析
    云原生在各大厂的落地与分析
    jni-02、lib路径、数组、对象、引用、extern修饰函数
    华为机试 - 最长的顺子
    nextjs引入tailwindcss 、antd、sass
    SOLIDWORKS二次开发——拓展设计能力与定制化解决方案
    Java项目:ssm+mysql+maven养老院管理系统
  • 原文地址:https://blog.csdn.net/qq_44918090/article/details/134075633