Вызов перегруженных функций C ++ из C DLL

0

Существует приложение (Proteus VSM), написанное в MSVC C++, которое поддерживает плагины на основе DLL.

DLL, созданная g++ (mingw32), несовместима с MSVC, __thiscall и другим способом не помогают. Большая часть моего кода написана в 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
    Вы понимаете, что каждая перегрузка будет иметь собственную запись в vtable?
  • 0
    Да, но есть ли способ ограничить его использование конкретной?
Показать ещё 2 комментария
Теги:
dll
overloading
mingw

1 ответ

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 просто дайте им разные имена и вызовите тот, который вы хотите.

  • 0
    Боже мой, так просто. Большое спасибо! Кажется, я плохо понимаю, как работает vtable

Ещё вопросы

Сообщество Overcoder
Наверх
Меню