Наследование С++ классов

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Ответить
Аватара пользователя
AlexVinS
новенький
Сообщения: 95
Зарегистрирован: 27.01.2009 00:18:01

Наследование С++ классов

Сообщение AlexVinS »

Пишу плагин для миранды. В версии 0.8 появилась возможность кое-что писать объектно ориентировано.

В частности есть такой класс:

Код: Выделить всё

#ifndef __cplusplus
typedef struct tagPROTO_INTERFACE_VTBL
{
   HANDLE    ( *AddToList )( struct tagPROTO_INTERFACE*, int flags, PROTOSEARCHRESULT* psr );
//куча ссылок на функции
}
   PROTO_INTERFACE_VTBL;
#endif
typedef struct tagPROTO_INTERFACE
{
   #ifndef __cplusplus
      PROTO_INTERFACE_VTBL* vtbl;
   #endif

   int    m_iStatus,
   //другие поля
#ifdef __cplusplus
   virtual   HANDLE   __cdecl AddToList( int flags, PROTOSEARCHRESULT* psr ) = 0;
    //еще куча чисто виртульных методов
#endif
}
   PROTO_INTERFACE;



Можно заметить что tagPROTO_INTERFACE_VTBL - это как раз таблица виртуальных методов. На сколько это совместимо в FPC если я буду писать примерно так:

Код: Выделить всё

TPROTO_INTERFACE =  object 
    iStatus       :int;
//остальные поля

    function    AddToList       (flags:int; var psr:TPROTOSEARCHRESULT):THANDLE; cdecl; virtual; abstract;
//остальные методы

end;


наследовать этот объект, и передавать ссылку на потомка в с++ ный код. Сработает?
Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

Сообщение Mr.Smart »

Таблицу вирталных (и не только) методов каждый компилятор строит по своему. И я недумаю, что возможно какое бы наследование с С++ классами :wink:
Аватара пользователя
AlexVinS
новенький
Сообщения: 95
Зарегистрирован: 27.01.2009 00:18:01

Сообщение AlexVinS »

Mr.Smart писал(а):Таблицу вирталных (и не только) методов каждый компилятор строит по своему. И я недумаю, что возможно какое бы наследование с С++ классами :wink:


Я же привел формат vmt как он в данном случае определен и спрашиваю такой же будет в fpc или нет.


Дож писал(а):http://xproger.livejournal.com/24653.html
http://xproger.livejournal.com/25176.html


То что касается дельфи в данном случае не интересует. Там все по другому.
Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

Сообщение Mr.Smart »

Нет вы формат VTM не привели! В случае компиляции под С++ структура будет прставленна как класс с виртуальными методами! Иначи будет структура с указателями на функции которые некакого отношения к ООП неимеют!
Аватара пользователя
AlexVinS
новенький
Сообщения: 95
Зарегистрирован: 27.01.2009 00:18:01

Сообщение AlexVinS »

Mr.Smart писал(а):Нет вы формат VTM не привели! В случае компиляции под С++ структура будет прставленна как класс с виртуальными методами! Иначи будет структура с указателями на функции которые некакого отношения к ООП неимеют!


Там стоит условная компиляция. При компиляции в с++ получается класс с виртуальными методами а на чистом С структура с указателем на tagPROTO_INTERFACE_VTBL. Причем вызавающий код НЕ ЗНАЕТ под чем скомпилирован плагин, тоесть tagPROTO_INTERFACE_VTBL - есть в точности формат таблицы виртуальных методов для данной структуры.

Добавлено спустя 3 минуты 23 секунды:
код полностью

Код: Выделить всё

#ifndef M_PROTOINT_H__
#define M_PROTOINT_H__ 1

typedef enum
{
   EV_PROTO_ONLOAD,
   EV_PROTO_ONREADYTOEXIT,
   EV_PROTO_ONEXIT,
   EV_PROTO_ONRENAME,
   EV_PROTO_ONOPTIONS
}
   PROTOEVENTTYPE;

#ifndef __cplusplus
typedef struct tagPROTO_INTERFACE_VTBL
{
   HANDLE    ( *AddToList )( struct tagPROTO_INTERFACE*, int flags, PROTOSEARCHRESULT* psr );
   HANDLE    ( *AddToListByEvent )( struct tagPROTO_INTERFACE*, int flags, int iContact, HANDLE hDbEvent );

   int       ( *Authorize )( struct tagPROTO_INTERFACE*, HANDLE hContact );
   int       ( *AuthDeny )( struct tagPROTO_INTERFACE*, HANDLE hContact, const char* szReason );
   int       ( *AuthRecv )( struct tagPROTO_INTERFACE*, HANDLE hContact, PROTORECVEVENT* );
   int       ( *AuthRequest )( struct tagPROTO_INTERFACE*, HANDLE hContact, const char* szMessage );

   HANDLE    ( *ChangeInfo )( struct tagPROTO_INTERFACE*, int iInfoType, void* pInfoData );

   HANDLE    ( *FileAllow )( struct tagPROTO_INTERFACE*, HANDLE hContact, HANDLE hTransfer, const char* szPath );
   int       ( *FileCancel )( struct tagPROTO_INTERFACE*, HANDLE hContact, HANDLE hTransfer );
   int       ( *FileDeny )( struct tagPROTO_INTERFACE*, HANDLE hContact, HANDLE hTransfer, const char* szReason );
   int       ( *FileResume )( struct tagPROTO_INTERFACE*, HANDLE hTransfer, int* action, const char** szFilename );

   DWORD_PTR ( *GetCaps )( struct tagPROTO_INTERFACE*, int type, HANDLE hContact );
   HICON     ( *GetIcon )( struct tagPROTO_INTERFACE*, int iconIndex );
   int       ( *GetInfo )( struct tagPROTO_INTERFACE*, HANDLE hContact, int infoType );

   HANDLE    ( *SearchBasic )( struct tagPROTO_INTERFACE*, const char* id );
   HANDLE    ( *SearchByEmail )( struct tagPROTO_INTERFACE*, const char* email );
   HANDLE    ( *SearchByName )( struct tagPROTO_INTERFACE*, const char* nick, const char* firstName, const char* lastName );
   HWND      ( *SearchAdvanced )( struct tagPROTO_INTERFACE*, HWND owner );
   HWND      ( *CreateExtendedSearchUI )( struct tagPROTO_INTERFACE*, HWND owner );

   int       ( *RecvContacts )( struct tagPROTO_INTERFACE*, HANDLE hContact, PROTORECVEVENT* );
   int       ( *RecvFile )( struct tagPROTO_INTERFACE*, HANDLE hContact, PROTORECVFILE* );
   int       ( *RecvMsg )( struct tagPROTO_INTERFACE*, HANDLE hContact, PROTORECVEVENT* );
   int       ( *RecvUrl )( struct tagPROTO_INTERFACE*, HANDLE hContact, PROTORECVEVENT* );

   int       ( *SendContacts )( struct tagPROTO_INTERFACE*, HANDLE hContact, int flags, int nContacts, HANDLE* hContactsList );
   HANDLE    ( *SendFile )( struct tagPROTO_INTERFACE*, HANDLE hContact, const char* szDescription, char** ppszFiles );
   int       ( *SendMsg )( struct tagPROTO_INTERFACE*, HANDLE hContact, int flags, const char* msg );
   int       ( *SendUrl )( struct tagPROTO_INTERFACE*, HANDLE hContact, int flags, const char* url );

   int       ( *SetApparentMode )( struct tagPROTO_INTERFACE*, HANDLE hContact, int mode );
   int       ( *SetStatus )( struct tagPROTO_INTERFACE*, int iNewStatus );

   HANDLE    ( *GetAwayMsg )( struct tagPROTO_INTERFACE*, HANDLE hContact );
   int       ( *RecvAwayMsg )( struct tagPROTO_INTERFACE*, HANDLE hContact, int mode, PROTORECVEVENT* evt );
   int       ( *SendAwayMsg )( struct tagPROTO_INTERFACE*, HANDLE hContact, HANDLE hProcess, const char* msg );
   int       ( *SetAwayMsg )( struct tagPROTO_INTERFACE*, int iStatus, const char* msg );

   int       ( *UserIsTyping )( struct tagPROTO_INTERFACE*, HANDLE hContact, int type );

   int       ( *OnEvent )( struct tagPROTO_INTERFACE*, PROTOEVENTTYPE iEventType, WPARAM wParam, LPARAM lParam );
}
   PROTO_INTERFACE_VTBL;
#endif

typedef struct tagPROTO_INTERFACE
{
   #ifndef __cplusplus
      PROTO_INTERFACE_VTBL* vtbl;
   #endif

   int    m_iStatus,
          m_iDesiredStatus,
          m_iXStatus,
          m_iVersion;
   TCHAR* m_tszUserName;
   char*  m_szProtoName;
   char*  m_szModuleName;

   DWORD  reserved[ 40 ];

   #ifdef __cplusplus
   virtual   HANDLE   __cdecl AddToList( int flags, PROTOSEARCHRESULT* psr ) = 0;
   virtual   HANDLE   __cdecl AddToListByEvent( int flags, int iContact, HANDLE hDbEvent ) = 0;

   virtual   int      __cdecl Authorize( HANDLE hDbEvent ) = 0;
   virtual   int      __cdecl AuthDeny( HANDLE hDbEvent, const char* szReason ) = 0;
   virtual   int      __cdecl AuthRecv( HANDLE hContact, PROTORECVEVENT* ) = 0;
   virtual   int      __cdecl AuthRequest( HANDLE hContact, const char* szMessage ) = 0;

   virtual   HANDLE   __cdecl ChangeInfo( int iInfoType, void* pInfoData ) = 0;

   virtual   HANDLE   __cdecl FileAllow( HANDLE hContact, HANDLE hTransfer, const char* szPath ) = 0;
   virtual   int      __cdecl FileCancel( HANDLE hContact, HANDLE hTransfer ) = 0;
   virtual   int      __cdecl FileDeny( HANDLE hContact, HANDLE hTransfer, const char* szReason ) = 0;
   virtual   int      __cdecl FileResume( HANDLE hTransfer, int* action, const char** szFilename ) = 0;

   virtual   DWORD_PTR __cdecl GetCaps( int type, HANDLE hContact = NULL ) = 0;
   virtual   HICON     __cdecl GetIcon( int iconIndex ) = 0;
   virtual   int       __cdecl GetInfo( HANDLE hContact, int infoType ) = 0;

   virtual   HANDLE    __cdecl SearchBasic( const char* id ) = 0;
   virtual   HANDLE    __cdecl SearchByEmail( const char* email ) = 0;
   virtual   HANDLE    __cdecl SearchByName( const char* nick, const char* firstName, const char* lastName ) = 0;
   virtual   HWND      __cdecl SearchAdvanced( HWND owner ) = 0;
   virtual   HWND      __cdecl CreateExtendedSearchUI( HWND owner ) = 0;

   virtual   int       __cdecl RecvContacts( HANDLE hContact, PROTORECVEVENT* ) = 0;
   virtual   int       __cdecl RecvFile( HANDLE hContact, PROTORECVFILE* ) = 0;
   virtual   int       __cdecl RecvMsg( HANDLE hContact, PROTORECVEVENT* ) = 0;
   virtual   int       __cdecl RecvUrl( HANDLE hContact, PROTORECVEVENT* ) = 0;

   virtual   int       __cdecl SendContacts( HANDLE hContact, int flags, int nContacts, HANDLE* hContactsList ) = 0;
   virtual   HANDLE    __cdecl SendFile( HANDLE hContact, const char* szDescription, char** ppszFiles ) = 0;
   virtual   int       __cdecl SendMsg( HANDLE hContact, int flags, const char* msg ) = 0;
   virtual   int       __cdecl SendUrl( HANDLE hContact, int flags, const char* url ) = 0;

   virtual   int       __cdecl SetApparentMode( HANDLE hContact, int mode ) = 0;
   virtual   int       __cdecl SetStatus( int iNewStatus ) = 0;

   virtual   HANDLE    __cdecl GetAwayMsg( HANDLE hContact ) = 0;
   virtual   int       __cdecl RecvAwayMsg( HANDLE hContact, int mode, PROTORECVEVENT* evt ) = 0;
   virtual   int       __cdecl SendAwayMsg( HANDLE hContact, HANDLE hProcess, const char* msg ) = 0;
   virtual   int       __cdecl SetAwayMsg( int iStatus, const char* msg ) = 0;

   virtual   int       __cdecl UserIsTyping( HANDLE hContact, int type ) = 0;

   virtual   int       __cdecl OnEvent( PROTOEVENTTYPE iEventType, WPARAM wParam, LPARAM lParam ) = 0;
   #endif
}
   PROTO_INTERFACE;

#endif // M_PROTOINT_H__

Mr.Smart
долгожитель
Сообщения: 1796
Зарегистрирован: 29.03.2008 00:01:11
Откуда: из леса!

Сообщение Mr.Smart »

допустим,что да. Только в совместимости с FPC насколько я знаю небудет!
Поищите по форуму сдесь поднималась тема о разнице VTM объектов и классов :wink:
Аватара пользователя
Дож
энтузиаст
Сообщения: 900
Зарегистрирован: 12.10.2008 16:14:47

Сообщение Дож »

То что касается дельфи в данном случае не интересует. Там все по другому.

Эх вы, не почитали, ссылки не посмотрели. О комментах вообще не говорю :)

Порядок методов в исполняемой программе сильно зависит не только от компилятора C++, но и от его версии. Например, Visual C++ начиная с какой-то версии стал сортировать overload методы. Кроме того C++ может автоматически создать на класс несколько конструкторов - и в FPC коде их придется тоже прописать.
наследовать этот объект, и передавать ссылку на потомка в с++ ный код. Сработает?

Попробуй, это не предсказать.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
Сообщения: 1409
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение Sergei I. Gorelkin »

Вообще вся эта конструкция напоминает то, как пишутся интерфейсы на чистом Си. Если это на самом деле так, то на FPC можно изобразить нечто вполне совместимое с помощью встроенной поддержки интерфейсов.
Аватара пользователя
AlexVinS
новенький
Сообщения: 95
Зарегистрирован: 27.01.2009 00:18:01

Сообщение AlexVinS »

Дож писал(а):Эх вы, не почитали, ссылки не посмотрели. О комментах вообще не говорю

ссылки смотрел, зря вы так.

Дож писал(а):
наследовать этот объект, и передавать ссылку на потомка в с++ ный код. Сработает?

Попробуй, это не предсказать.


Попробовал, словил глюков и пока от этой затеи отказался. Написал врапер.

Sergei I. Gorelkin писал(а):Вообще вся эта конструкция напоминает то, как пишутся интерфейсы на чистом Си. Если это на самом деле так, то на FPC можно изобразить нечто вполне совместимое с помощью встроенной поддержки интерфейсов.


А вот это интересно, спасибо.
ViTality
постоялец
Сообщения: 308
Зарегистрирован: 05.10.2007 15:12:02

Сообщение ViTality »

AlexVinS а не могли бы вы поделиться заголовками плагинов миранды для freepascal/lazarus?
Ответить