将指针传递给DLL中的成员函数

时间:2013-06-10 12:34:03

标签: c++ dll member-function-pointers

我有一个DLL,它被我没有创建的程序作为插件加载,它的目的是在程序内部的数组中替换指向成员函数的指针,以便为加载它的现有程序提供附加功能。

程序(加载插件dll)的源代码如下所示

//Core object that all objects inherit
class MObject
{
public:
    //variables

    //functions
}

enum ECmdIndex
{
    CMD_RUN = 0x0,
    //ect
    CMD_MAX = 0x500
}
//Global command list of command functions
typedef void (MObject::*CommandFunc)(SContext&, void*)
CommandFunc GCommands[CMD_MAX];

//Example command function
void MObject::funcCmdRun(SContext& context, void* result)
{
    //do stuff
}
GCommands[CMD_RUN] = &MObject::funcCmdRun;

//This is used to execute command functions
void MObject::ProcessCommand( SContext& context, void* result )
{
    //ect

    //Execute the command's function on this MObject
    //Here is where my function should replace the default one
    (this->*GCommands[context.cmdInd])(context, result);

    //ect
}

我的DLL非常简单。它主要用DLL中的一个替换程序的GCommands数组中的命令函数。

//MObject structure is replicated exactly in the DLL
//This is neccesary because my plugin is going beyond the provided API
//And so this is becoming a bit "hacky"
class MObject
{
public:
    //variables

    //functions
}

typedef void (MObject::*CommandFunc)(SContext&, void*)

void MObject::MyCommandFunc(SContext& context, void* result)
{
    //do stuff
}

void onLoad()
{
    //Get a pointer to GCommands array
    CommandFunc** pGCommands = GetGCommandOffset();

    //Replaced the desired command function with the new one
    pGCommand[0x1B] = &MObject::MyCommandFunc;
}

简要摘要:宿主程序调用成员函数指针。我的DLL应该使指针指向它自己的函数,并且当主机应用程序调用该指针时,必须使该函数可调用。

问题是我的新命令功能从未输入,并且在程序中执行时命令不再执行任何操作。我至少会发生一次撞车事故。我为代码固有的hacky外观道歉,但肯定有正确的方法来实现这个目标吗?

1 个答案:

答案 0 :(得分:1)

这里的根本原因似乎是ODR违规。您的主机应用程序使用MyCommandFunc的一个实现(或根本没有实现)定义一个MObject,并且您的DLL使用另一个实现定义它。你在这里尝试做什么(通过一系列函数指针在每个成员函数的基础上覆盖类功能)很奇怪,并且永远不会在可移植的情况下工作。

如果你有一堆在MObject上运行的命令,你可以将它们声明为带有MObject的非成员(或静态成员)函数,并且有一个数组。 (你可以将它们作为MObjectCommand虚拟接口的实现公开,但它看起来不像你需要任何状态,所以这可能是不必要的。)