1

Topic: The interface of a plug-in and it vtable

Kind time of days, dear colleagues! An essence of a question that we in development about one year have an application on a C ++ (MSVC2015) with plug-ins. The idea put in system of plug-ins, is is short stated here: http://www.andynicholas.com/?p=27 In a basis of the interface of a plug-in (aka the abstract base class in a C context ++)  has been put such here the code: class IPluginlInterface {public: virtual ~IPluginInterface () {}; virtual void Init () = 0; virtual char* GetInterfaceName () const = 0; virtual char* GetInterfaceDescription () const = 0; virtual char* GetInterfaceVersion () const = 0; virtual char* GetInterfaceDateTime () const = 0; virtual int GetInterfaceCategory () const = 0; virtual int GetInterfaceFlags () const = 0; virtual void SetCallbackNotifyer (INotifyer1* pNotyfier) = 0; virtual void SetIXMLConfigPointer (IXMLConfig* pXMLConfig) = 0; virtual void SetIDALPointer (IDAL* pIDAL) = 0; virtual void SetDataItem1 (DataItem1* pItem) = 0; virtual void SetDataItem2 (DataItem2* pItem) = 0; virtual void SetBackupOptions (int iOptions) = 0; virtual INotifyer1* GetCallbackNotifyer () const = 0; virtual DataItem1* GetDataItem1 () const = 0; virtual DataItem2* GetDataItem2 () const = 0; virtual long PerformCalculations () = 0; virtual void DeInit (int& aiDeInitCounter) = 0;} ; This version - the very first (old). Now the interface develops - new virt-methods are added. I suggest them to add in the end - after DeInit. It allows to use those plug-ins which were compiled under the old version of the interface. The fellow worker added new method SuspendCalculations. Thus made so: class IPluginlInterface {public: virtual ~IPluginInterface () {}; virtual void Init () = 0; virtual char* GetInterfaceName () const = 0; virtual char* GetInterfaceDescription () const = 0; virtual char* GetInterfaceVersion () const = 0; virtual char* GetInterfaceDateTime () const = 0; virtual int GetInterfaceCategory () const = 0; virtual int GetInterfaceFlags () const = 0; virtual void SetCallbackNotifyer (INotifyer1* pNotyfier) = 0; virtual void SetIXMLConfigPointer (IXMLConfig* pXMLConfig) = 0; virtual void SetIDALPointer (IDAL* pIDAL) = 0; virtual void SetDataItem1 (DataItem1* pItem) = 0; virtual void SetDataItem2 (DataItem2* pItem) = 0; virtual void SetBackupOptions (int iOptions) = 0; virtual INotifyer1* GetCallbackNotifyer () const = 0; virtual DataItem1* GetDataItem1 () const = 0; virtual DataItem2* GetDataItem2 () const = 0; virtual long SuspendCalculations () = 0;//this new virt-method Is added!!! virtual long PerformCalculations () = 0; virtual void DeInit (int& aiDeInitCounter) = 0;} ; Then, in my codes instead of call DeInit there was call PerformCalculations. It and is clear, as on a position where earlier in the table of the virtual functions was DeInit "moved" PerformCalculations. In general - a problem I . Nevertheless, while the question is opened such here: I suppose that all new virt-methods should be added after DeInit, it provides start of old plug-ins. The fellow worker suggests to allocate how it seems more logically (without orientation to compatibility with  plug-ins), motivating it with that all plug-ins also is necessary . And as though  you respected? P.S. Technology COM not to offer. I worked earlier with COM much and I know this technology, however to use in our project I do not want. COM adds superfluous complexities there where them absolutely at all it is not required.

2

Re: The interface of a plug-in and it vtable

Hello, AlexGin, you wrote: AG> I suppose that all new virt-methods should be added after DeInit, it provides start of old plug-ins. AG> the fellow worker suggests to allocate how it seems more logically (without orientation to compatibility with  plug-ins), AG> motivating it with that all plug-ins also is necessary . Whether you there are defined backward compatibility with old plug-ins is necessary or not. As soon as be defined, also the decision can accept about reverse compatibility: I worked with similar system and there the virtual methods were added in the end (there it was necessary to support backward compatibility) and here once after adding of the next method compatibility broke. It appeared that if the method with a name is added, which already is (but with another arguments, for example) the studio compiler breaks the order of methods, grouping methods with an identical name so be attentive

3

Re: The interface of a plug-in and it vtable

Hello, AlexGin, you wrote: This very strange decision to be fastened on binary representation vtbl More correctly, in my opinion, to make the new interface: class IPluginlInterface2: public IPluginlInterface {virtual long SuspendCalculations () = 0;//this new virt-method Is added!!!} all new plug-ins will use it, and in the program to make  for old interfaces: class IPluginlInterfaceWrapper: public IPluginlInterface2 {public: IPluginlInterfaceWrapper (IPluginlInterface * old_plugin); virtual void Init () {old_plugin-> Init ();} virtual char* GetInterfaceDescription () const {return old_plugin-> GetInterfaceDescription ();}... virtual long SuspendCalculations () {/* How to be? */}}

4

Re: The interface of a plug-in and it vtable

Hello, uzhas, you wrote: whether U> you there are defined backward compatibility with old plug-ins is necessary or not. Generally it is not mandatory. As all plug-ins are all the same fastened on head application. Outside developers/companies who would be engaged  plug-ins to our system while are not present. More precisely - meanwhile it is not foreseen. U> as soon as be defined, also the decision can accept Well  for the decision important as well to look forward - today compatibility it is not actual, and tomorrow... U> about reverse compatibility: I worked with similar system and there the virtual methods were added in the end (there it was necessary to support backward compatibility) and here once after adding of the next method compatibility broke. U> it appeared that if the method with a name is added, which already is (but with another arguments, for example) the studio compiler breaks the order of methods, grouping methods with identical name U> so be attentive It the interesting fact. The overload of the virtual methods, in general also can take place. I will not argue Here. It turns out that compatibility based on such assumption that we add virt-methods in the end - inconsistent in general - thanks, for council, we take into consideration.

5

Re: The interface of a plug-in and it vtable

Hello, ffk, you wrote: ffk> Hello, AlexGin, you wrote: ffk> This very strange decision to be fastened on binary representation vtbl Yes, the decision it not the best, itself I feel. Therefore and council I ask ffk> More correctly, in my opinion, to make the new interface: ffk> ffk> class IPluginlInterface2: public IPluginlInterface ffk> {ffk> virtual long SuspendCalculations () = 0;//this new virt-method Is added!!! ffk>} ffk> it is possible that it is good idea ffk> All new plug-ins will use it, and in the program to make  for old interfaces: ffk> ffk> class IPluginlInterfaceWrapper: public IPluginlInterface2 ffk> {ffk> public: ffk> IPluginlInterfaceWrapper (IPluginlInterface * old_plugin); ffk> virtual void Init () {old_plugin-> Init ();} ffk> virtual char* GetInterfaceDescription () const {return old_plugin-> GetInterfaceDescription ();} ffk>... ffk> virtual long SuspendCalculations () {/* How to be? */} ffk>} ffk> the decision like as interesting... At the same time: here and inheritance (from basic IPluginlInterface) and aggregation ( old_plugin). Whether Not too it is a lot of all? What popular pattern of designing on this subject can is?

6

Re: The interface of a plug-in and it vtable

Hello, AlexGin, you wrote: ffk>> [/ccode] AG> the Decision like as interesting... AG> At the same time: here and inheritance (from basic IPluginlInterface) and aggregation ( old_plugin). Whether AG> Not too it is a lot of all? AG> what popular pattern of designing on this subject can is? Yes. Wrapper aka Adapter. Inheritance and aggregation here is normal. You should to force work "an old" plug-in with new requirements. For this purpose you turn each method. If at you the logic of a call of methods you process it in  changes. For example, in the first version   that in method SetDataItem1 cannot transfer nullptr, and in the second you do not guarantee it, can process it in . In such approach the compatibility point is localized. Your program can forget generally about old interfaces and contracts for them and to work only with the new. P.S. Inheritance is not mandatory, I would not do it.

7

Re: The interface of a plug-in and it vtable

Hello, AlexGin, you wrote: AG> And as though  you respected? If all under Windows I would select most likely COM, and all complexity of operation with it hid in  system and zastvil/taught all to use . AG> COM adds superfluous complexities there where them absolutely at all it is not required. Where, for example?

8

Re: The interface of a plug-in and it vtable

Hello, Kernan, you wrote: K> Hello, AlexGin, you wrote: AG>> And as though  you respected? There is one more variant, to connect plug-ins is not binary, and through a certain broker (for example, dbus) or, for example, popular today message queue. In most it is simple the approach, each plug-in communicates with a kernel through loopback a socket, in this case it is not necessary  with ABI, and adding of new messages will transit very quickly + there are no problems with reverse compatibility. From COM truth here not so is a lot of conceptual difference.

9

Re: The interface of a plug-in and it vtable

Hello, Kernan, you wrote: K> Hello, AlexGin, you wrote: AG>> And as though  you respected? K> if all under Windows I would select most likely COM, and all complexity of operation with it hid in  system and zastvil/taught all to use . While under Windows, but we use Qt 5.9 and in the long term we can pass on  (Linux: Ubuntu, Debian). About  systems: we work with QMake which can be applied both in native to it QtCreator, and in MSVC (through QtVsAddin). At the given stage of the project to apply something another, except the given simple decision, we do not plan. AG>> COM adds superfluous complexities there where them absolutely at all it is not required. K> Where, for example? As in the bases: 1) Basic  IUnknown (here: https://msdn.microsoft.com/en-us/librar … p/ms680509 (v=vs.85).aspx) has in the composition virt-methods AddRef and Release. Yes, in 1990 it it was actual, however now when already is officially recognized std:: : shared_ptr  idea IUnknown lost any urgency. 2) the superfluous inheritance which completely not has been not dictated by requirements of the application-oriented task, - also an overhead projector. And in implementation: a) Generation of entities in the form of GUID, called to eliminate "DLL hell", seems to me all the same superfluous, except for a situation - if we the company of level M $, offering the products of milliard audience b) Interface definition language MIDL (https://msdn.microsoft.com/en-us/library/windows/desktop/aa367091 (v=vs.85).aspx) also superfluous (in  application-oriented tasks) essence. Its presence only complicates the project codes. c) support and development of projects on the basis of COM much more , than without COM. Here I imply as all custom actions (in the same studio),  are directed on support of infrastructure COM, however, are not actual (from a word absolutely) for the application-oriented task; and attending process (the documentation on the project and its support). Except all it, I (as ) applying COM should type in my working group of the people owning given (nowadays not actual) technology, or to train an existing command operation with it. It also - superfluous  P.S. Yes,  idea - to make COM a component and to apply in the different language environments (a C, a C ++, VB) - originated about quarter of the century back, was , but now idea the urgency lost, and excessive complexity - remained

10

Re: The interface of a plug-in and it vtable

Hello, AlexGin, you wrote: AG> It turns out that compatibility based on such assumption that we add virt-methods in the end - inconsistent is certain cunnings which should be held in a head. Actually ABI on a C ++ interfaces - quite efficient subject. It is good the simplicity and absence of an overhead charge for calls. But certain accuracy and vigilance is necessary. Difficult types (for example, std:: vector) not  through such API at present I also work with similar system so they are quite spread as they say, the devil is not so terrible as he is painted

11

Re: The interface of a plug-in and it vtable

Hello, uzhas, you wrote: U> Hello, AlexGin, you wrote: AG>> It turns out that compatibility based on such assumption that we add virt-methods in the end - inconsistent U> is certain cunnings which should be held in a head. U> actually ABI on a C ++ interfaces - quite efficient subject. It is good the simplicity and absence of an overhead charge for calls. But certain accuracy and vigilance is necessary. +100500 you, respected uzhas, under selected, implied approximately it: https://stackoverflow.com/questions/217 … erface-abi http://alenacpp.blogspot.com.by/2007/03/c-abi.html U> difficult types (for example, std:: vector) not  through such API +100500 Yes, object in the method interface ! But the pointer to object of type std:: vector to transfer (at level of the interface method led to type void *), IMHO it is quite possible. . U> at present I also work with similar system so they are quite spread U> as they say, the devil is not so terrible as he is painted Here and I would not like "to drag in the project" complexity COM, that all code of the project of dews as "a snow clod"

12

Re: The interface of a plug-in and it vtable

Hello, AlexGin, you wrote: AG> And as though  you respected? I  lua for plug-ins would use language.

13

Re: The interface of a plug-in and it vtable

Hello, AlexGin, you wrote: AG> While under Windows, but we use Qt 5.9 and in the long term we can pass on  (Linux: Ubuntu, Debian). In QT there is a library for creation of plug-ins. Why it not to use? It works and just solves all described above a problem. P.S. I do not agree with your outputs concerning COM, but to argue here there is no sense.

14

Re: The interface of a plug-in and it vtable

Hello, AlexGin, you wrote: AG> under selected, implied approximately it: AG> https://stackoverflow.com/questions/217 … erface-abi yes, it it U>> difficult types (for example, std:: vector) not  through such API AG> +100500 AG> Yes, object in the method interface ! AG> But the pointer on object of type std:: vector to transfer (at level of the interface method led to type void *), AG> IMHO it is quite possible... A prothrow std containers between different (exe/dll units - even more fragile ABI. I and with the such worked. Here normally do so that all  gather simultaneously one compiler with the same adjustments for a C ++ runtime, in particular, disconnect static  well and with debug/release it is necessary not to be confused. I would not recommend to go such way. Since in a head of even more details it is necessary to hold) better not to transfer containers since in different units they can have a bit different implementation. Here we from one  in the second transferred let even the pointer on std:: vector. Whether the second can  at least  on this vector? Only under certain circumstances as compilation settings STL (for example, https://stackoverflow.com/questions/473 … al-studio) it is better to transfer that T* + int size

15

Re: The interface of a plug-in and it vtable

Hello, Kernan, you wrote: K> Hello, AlexGin, you wrote: AG>> While under Windows, but we use Qt 5.9 and in the long term we can pass on  (Linux: Ubuntu, Debian). K> In QT there is a library for creation of plug-ins. +100500 so we also use it in our project! This point in question, on interface development, does not cancel application QtPlugin. In my initiating post I did not specify that is applied QtPlugin, is simple because did not want to load colleagues on a forum superfluous details. K> why it not to use? It works and just solves all described above a problem. There it is added (at level of the interface of a plug-in), additional inheritance from QObject. How it can solve the question specified in initiating my post of the given topic? If have any image on the given aspect, respected Kernan, please state it. K> P.S. I do not agree with your outputs concerning COM, but to argue here there is no sense. I stated my point of view generated in an operating time with COM in 2000. This technology was applied within the precincts of the several companies, in  I then worked. P.S. In our project important to solve that problem that is actual for the given task I Tend to "adapter" application: https://habrahabr.ru/post/85095 https://gist.github.com/pazdera/1145857 https://www.codeproject.com/Tips/595716 … -Cplusplus

16

Re: The interface of a plug-in and it vtable

Hello, kov_serg, you wrote: _> Hello, AlexGin, you wrote: AG>> And as though  you respected? _> I  language lua for plug-ins would use. Whether it is necessary to enter new entities into the project? As all (in respect of the interface of plug-ins) some small adjustments are already made, possible. In general, the subsystem of plug-ins quite suits us, the small question described by me in the beginning of a topic - should have the adequate decision.

17

Re: The interface of a plug-in and it vtable

Hello, AlexGin, you wrote: AG> So we also use it in our project! Probably, not absolutely correctly. AG> in my initiating post I did not specify that is applied QtPlugin, is simple because did not want to load colleagues on a forum superfluous details. The most important also you do not specify. K>> why it not to use? It works and just solves all described above a problem. AG> there it is added (at level of the interface of a plug-in), additional inheritance from QObject. It not so. There the macro in a class and after  a class is added then is run through meta-compiler QT, study the documentation better, there all it is. I on your place  the minimum project and  operation with qt-plug-ins or downloaded a minimum example where they are used and  it. AG> as it can solve the question specified in initiating my post of the given topic? Studying docks and understanding as it is all it is necessary to use correctly you, most likely, you will solve the problems.

18

Re: The interface of a plug-in and it vtable

Hello, AlexGin, you wrote: a question: AG> I suppose that all new virt-methods should be added after DeInit, it provides start of old plug-ins. AG> the fellow worker suggests to allocate how it seems more logically (without orientation to compatibility with  plug-ins), AG> motivating it with that all plug-ins also is necessary . AG> and as though  you respected? As a variant to make the first method of the interface that the interface version returned. And to change it at all incompatible changes. Then old plug-ins can be thrown out at a loading stage, instead of to look at unforeseen behavior after.

19

Re: The interface of a plug-in and it vtable

Hello, AlexGin, you wrote: AG> Hello, kov_serg, you wrote: _>> Hello, AlexGin, you wrote: AG>>> And as though  you respected? _>> I  language lua for plug-ins would use. Whether AG> it is necessary to enter new entities into the project? Depends on project tasks. Skriptovyj language more floppy also allows to add the normal text editor a missing functional. Unlike , it is possible to rectify errors in already available to add or on their basis to do the similar. A low threshold of an input. . Is More indicative. If needed can easy cause binary  for performance of heavy calculations. AG> as all (in respect of the interface of plug-ins) some small adjustments are already made, possible. AG> in general, the subsystem of plug-ins quite suits us, the small question described by me in the beginning of a topic - should have the adequate decision. AG> the Fellow worker suggests to allocate how it seems more logically (without orientation to compatibility with  plug-ins), there Should be a binary compatibility and the mechanism of check of versions. I would add still sign-code signatures that each time on viruses not to check AG> motivating it with that all plug-ins also is necessary . And if plug-ins are indirect and the plug-in working in the old version suddenly will miss on the new. For example a plug-in working with bank cards. Updated on and cards  are not accepted. Beauty.

20

Re: The interface of a plug-in and it vtable

Hello, Alexander G, you wrote: AG> Hello, AlexGin, you wrote: AG> a question: AG>> I suppose that all new virt-methods should be added after DeInit, it provides start of old plug-ins. AG>> the fellow worker suggests to allocate how it seems more logically (without orientation to compatibility with  plug-ins), AG>> motivating it with that all plug-ins also is necessary . AG>> and as though  you respected? AG> as a variant to make the first method of the interface that the interface version returned. And to change it at all incompatible changes. AG> then old plug-ins can be thrown out at a loading stage, instead of to look at unforeseen behavior after. It would be necessary what not the plug-in checked, and application. And the plug-in simply asked the interface known to it (at the moment of plug-in writing) to application. And here application can some  support such interfaces. For example at a plug-in is init, done In init a plug-in  the software interface  give me the version of the interface 2.1 after or receives it or goes wood. app_runtime rt [1]; int init (queryfn fn) {if (fn.query (rt, APP_RUNTIME_VERSION_2_1) return-1; rt-> set_plugin_info (info); rt-> create_thread... rt-> add_menu_item... rt-> set_event_listner... rt-> add_resouce...... return 0;} void done () {//release resources used}

21

Re: The interface of a plug-in and it vtable

Hello, Kernan, you wrote: AG>> There it is added (at level of the interface of a plug-in), additional inheritance from QObject. K> It not so. There the macro in a class and after  a class is added then is run through meta-compiler QT, study the documentation better, there all it is. I on your place  the minimum project and  operation with qt-plug-ins or downloaded a minimum example where they are used and  it. Examples took, with them understood. At least that is declared by authors in an example, works successfully. Here such here macroes (except normal Q_OBJECT): Q_PLUGIN_METADATA (IID...) Q_INTERFACES (...) Probably, it is necessary to dig towards these macroes AG>> As it can solve the question specified in initiating my post of the given topic? K> studying docks and understanding as it is all it is necessary to use correctly you, most likely, you will solve the problems. Can quite be! Thanks, respected Kernan, I will look aside Qt-shnoj supports of plug-ins!

22

Re: The interface of a plug-in and it vtable

Hello, AlexGin, you wrote: AG> Kind time of days, dear colleagues! And what problems? class IPluginlInterface {public: static int iid () {return 1;} virtual IPluginlInterface* GetInterface (int id) const = 0; template <class IF> IF* Interface () const {return static_cast <IF *> (GetInterface (IF:: iid ()));}}; class IPluginlInterface2: IPluginlInterface {public: static int iid () {return 2;} virtual IPluginlInterface* GetInterface (int id) const {if (id == iid ()) return this; return IPluginlInterface:: GetInterface (id);}}; well and usage IPluginlInterface* pp =...; IPluginlInterface2* pp2 = pp-> Interface <IPluginlInterface2> ();

23

Re: The interface of a plug-in and it vtable

Hello, c-smile, you wrote:... The Beautiful decision, respected c-smile! I will mandatory try Spaspbo!