有一个应用程序(Proteus VSM),用MSVC C ++编写,支持基于DLL的插件。
由g ++(mingw32)生成的DLL与MSVC不兼容,__这个以及其他方式没有帮助。我的大部分代码都是用gcc / mingw编写的,并且有很多基于GAS的组装部分(不是为了加速)等等,因此很难仅为Windows DLL项目重写它(其他代码适用于Linux)
以下是SDK的原始标题:
class IDSIMPIN1
{ public:
virtual EVENT *setstate (ABSTIME time, RELTIME tlh, RELTIME thl, RELTIME tgq, STATE state) = 0;
virtual EVENT *setstate (ABSTIME time, RELTIME tgq, STATE state) = 0;
virtual VOID setstate (STATE state) = 0;
virtual VOID sethandler (IDSIMMODEL *model, PINHANDLERFN phf) = 0;
virtual DSIMNODE getnode() = 0;
virtual STATE getstate() = 0;
};
如您所见,函数 setstate 重载了三次。为了访问它,我在C中执行了以下操作:
#define __thiscall __attribute__((fastcall))
#define EDX DWORD EDX
typedef struct IDSIMPIN1 IDSIMPIN1;
typedef struct IDSIMPIN1_vtable IDSIMPIN1_vtable;
struct IDSIMPIN1_vtable
{
//EVENT* __thiscall (*setstate)(IDSIMPIN1 *this, EDX, ABSTIME time, RELTIME tgq, STATE state);
VOID __thiscall (*setstate)(IDSIMPIN1 *this, EDX, STATE state);
VOID __thiscall (*sethandler)(IDSIMPIN1 *this, EDX, IDSIMMODEL *model, PINHANDLERFN phf);
DSIMNODE __thiscall (*getnode)(IDSIMPIN1 *this, EDX);
STATE __thiscall (*getstate)(IDSIMPIN1 *this, EDX);
};
struct IDSIMPIN1
{
IDSIMPIN1_vtable *vtable;
};
现在我可以像这样访问这些函数:
IDSIMPIN1 *pin;
...
pin->vtable->setstate(pin, 0, SHI);
这适用于“普通”功能。但是,当谈到 setstate 时,它的工作方式并不像预期的那样。因为我不能在C中使用重载函数,所以我立刻尝试了其中一个。只有VOID“版本”按预期工作,其他版本的行为方式错误。
我不确定这是问题的根本原因,我知道它可能是奇怪的编程,但可能有人可以帮助我解决可能的问题(除了将代码移植到MSVC :) :)。
答案 0 :(得分:1)
每个重载在vtable中都有一个指针:
struct IDSIMPIN1_vtable
{
EVENT* __thiscall (*setstate1)(IDSIMPIN1 *, ABSTIME, RELTIME, RELTIME, RELTIME, STATE);
EVENT* __thiscall (*setstate2)(IDSIMPIN1 *, ABSTIME, RELTIME, STATE);
VOID __thiscall (*setstate3)(IDSIMPIN1 *, STATE);
VOID __thiscall (*sethandler)(IDSIMPIN1 *this, EDX, IDSIMMODEL *model, PINHANDLERFN phf);
DSIMNODE __thiscall (*getnode)(IDSIMPIN1 *this, EDX);
STATE __thiscall (*getstate)(IDSIMPIN1 *this, EDX);
};
在C中,只需给它们不同的名称并拨打你想要的名称即可。