C++ 跨DLL传递指向成员函数的指针

C++ 跨DLL传递指向成员函数的指针,c++,dll,member-function-pointers,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 } /

我有一个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应该使指针指向它自己的函数,并在宿主应用程序调用该指针时,执行必须的操作,使该函数可调用


问题是我的新命令函数从未被输入,并且当在程序中执行时,该命令不再执行任何操作。我至少可以预料会发生车祸。我为代码固有的黑客外观道歉,但肯定有一种正确的方法来实现这一点?

这里的根本原因似乎是违反了ODR。您的主机应用程序使用一个MyCommandFunc实现(或根本没有实现)定义MObject,而您的DLL使用另一个实现定义它。您在这里试图做的事情(通过一系列函数指针,在每个成员函数的基础上重写类功能)非常奇怪,而且永远也无法实现可移植性


如果您有一组在MObject上操作的命令,那么您可以将它们声明为接受MObject的非成员(或静态成员)函数,并具有这些函数的数组。(您可以将它们公开为MObjectCommand虚拟接口的实现,但它看起来不需要任何状态,因此这可能是不必要的。)

作为旁注,我发现了一些问题,如有帮助以及其中包含的链接。最终,它们还不足以解决我的问题。我认为重新定义跨DLL边界使用的对象会有很大的问题!应该在公共库或公共头中定义。你想实现什么?你有什么理由坚持这种设计吗?不幸的是,我坚持这种方法,因为MObject类根本没有公开,只在内部使用。插件API还很年轻,没有提供太多的功能和灵活性。你可能有点误解了这个问题。我无法控制主机应用程序的代码,因为它不是由我编写的。我正在编写一个DLL,该DLL由宿主应用程序加载,然后宿主应用程序将修改宿主应用程序中的指针以指向我的函数。问题是如何让宿主程序正确调用我的函数。如果这是一个常规函数指针,就不会有问题。此外,如果我必须(裸体)定义我的函数并自己编写prolog asm,如果这是被调用方的问题,我会这样做。