如何从主项目c ++加载DLL

Posted

技术标签:

【中文标题】如何从主项目c ++加载DLL【英文标题】:How to load the DLL from the main project c++ 【发布时间】:2014-01-31 16:41:48 【问题描述】:

我创建了一个项目,它使用 2 个 DLL 来相互对抗(一个 DLL 就是一个播放器)。游戏是第一个玩家选择一个数字,第二个玩家选择另一个数字,然后 PlayRound 函数将两个数字进行比较。我不确定如何加载 DLL(运行/加载时间)的问题。我创建了我的第一个 DLL (simple.dll),它有一个 Pick 函数,为简单起见总是返回“int 2”:

#include "stdafx.h"
#define ASEXPORT
#include <iostream>
#include "player.h"

using namespace std;

int Pick(int Round, int MyMoves[], int OpponentMoves[])

    return 2;

这个项目有一个头文件(player.h),代码如下:

#ifndef ASEXPORT
#define DLLIMPORTOREXPORT dllimport
#else
#define DLLIMPORTOREXPORT dllexport
#endif

_declspec(DLLIMPORTOREXPORT) int Pick(int Round, int MyMoves[], int OpponentMoves[]);

不确定在哪里包含此代码,我应该将它包含在 main 中还是函数中:

    HINSTANCE hinstLib; 
    MYPROC ProcAdd; 
    BOOL fFreeResult, fRunTimeLinkSuccess = FALSE; 

    // Get a handle to the DLL module.

    //hinstLib = LoadLibrary(TEXT(player2Name)); 

    hinstLib = LoadLibrary();
    // If the handle is valid, try to get the function address.

    if (hinstLib != NULL) 
     
        ProcAdd = (MYPROC) GetProcAddress(hinstLib, "simple.DLL"); 

        // If the function address is valid, call the function.

        if (NULL != ProcAdd) 
        
            fRunTimeLinkSuccess = TRUE;
            (ProcAdd) (L"Message sent to the DLL function\n"); 
        

        // Free the DLL module.
        fFreeResult = FreeLibrary(hinstLib); 
     

// Report any failures
    if (! fRunTimeLinkSuccess) 
        printf("Unable to load DLL or link to functions\n"); 
    if (! fFreeResult) 
        printf("Unable to unload DLL\n");
//

我希望我说得通俗易懂

【问题讨论】:

为什么选择运行时链接。加载时间链接和导入库 (.lib) 更容易 @DavidHeffernan load time linking?我猜你的意思是静态链接或至少编译时链接 @Paranaix 不,我的意思是加载时间链接:msdn.microsoft.com/en-us/library/windows/desktop/… @DavidHeffernan 我不介意加载时间或运行时间 如果您在加载时执行此操作,那么您将只能拥有一个播放器 DLL。 【参考方案1】:

您可以在 IndieZen 核心库中的 ModuleService 实现中看到这一点。我将 .dll 和 .so 视为“模块”。在我的插件系统中,我有一个标准,即每个模块都实现一个且只有一个导出函数,在我的示例中为 getModule(),在您的用例中为 Pick()

我的示例在I_Module 接口的实现中返回。在我的例子中,模块是插件的集合,所以你唯一能做的就是实现一个I_Plugin,它又可以用来访问类工厂,然后这些类工厂构造对象(扩展)它实现了预定义的接口(扩展点)。

我知道这对于您的示例来说太过分了,但是代码很容易理解;随意复制/粘贴您可以使用的子集。

关键是不要在Pick 函数上使用_declspec(DLLIMPORTOREXPORT);你应该只导出函数而不是导入它。您也不应该将这些 DLL 链接到您的主应用程序,也不应该将 DLL 的头文件包含到您的主应用程序中。这将使您能够灵活地导入两个单独的 DLL,它们公开相同的功能(在您的情况下为 Pick)而不会出现链接错误。它还可以让您在运行时才知道 DLL 的名称(您可能需要一些配置或 GUI 来让用户选择哪些播放器)。

我的实现,包括引用计数、类工厂等,会给你一个额外的优势,因为你可以在同一个 DLL 中实现两个玩家,它们可以互相对抗。

【讨论】:

以上是关于如何从主项目c ++加载DLL的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式在C ++或Python中列出DLL的依赖项?

如何在没有 Visual Studio 的情况下进行调试?

Visual Studio 如何加载库?

如何重新加载经常崩溃的第 3 方 DLL

如何在 Python 中从 SXS 加载 C DLL?

如何让 PostgreSQL 加载依赖 DLL 的 C 模块?