我创建了一个项目,它使用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");
//
我希望我能理解
答案 0 :(得分:1)
您可以在IndieZen核心库的ModuleService实现中看到这一点。我将.dll和.so视为“模块”。在我的插件系统中,我有一个标准,每个模块都实现一个且只有一个导出函数,在我的例子中是getModule()
,在你的用例中是Pick()
。
我的示例返回I_Module接口的实现。在我的示例中,模块是插件的集合,因此您唯一能做的就是获得I_Plugin的实现,这可以用来获取对类工厂的访问,然后这些类工厂构造对象(扩展)实现预定义的接口(扩展点)。
我知道你的例子有点过分,但代码很容易理解;随意复制/粘贴您可以使用的子集。
一个关键是不要在_declspec(DLLIMPORTOREXPORT)
函数上使用Pick
;您应该只导出该函数而不导入它。您也不应该将这些DLL链接到主应用程序,也不应将DLL的头文件包含到主应用程序中。这将使您能够灵活地导入两个单独的DLL,这些DLL暴露相同的函数(在您的情况下为Pick
),而不会出现链接错误。它还将为您提供在运行时之前不知道DLL名称的优势(可能您可能需要某些配置或GUI来让用户选择哪些玩家)。
我的实现,引用计数,类工厂等会给你一个额外的好处,你可以在同一个DLL中实现两个可以相互对抗的玩家。