【问题标题】:How to load the DLL from the main project c++如何从主项目c ++加载DLL
【发布时间】: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。

标签: c++ dll


【解决方案1】:

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-06
    • 2013-06-29
    • 2012-02-13
    • 1970-01-01
    • 1970-01-01
    • 2011-12-02
    • 1970-01-01
    • 2011-09-28
    相关资源
    最近更新 更多