It was many times said in this thread that we need a language and compiler independent ABI for new API. It was also suggested to have machine-generated API descriptions for different languages. It was also mentioned that we need a better way to combine C++ exceptions with status vector when performing API calls than always manually adding try/catch and check for an error in status vector.
I want to suggest a first draft of [very restricted] IDL implementation for firebird that should solve all mentioned problems. As an additional non-mentioned before feature it solves the problem of making interface version upgrade compiler independent and reliable. I do not use suggested here method of keeping interface in database and generating all needed from it. That's certainly simpler to generate but causes obvious problems at the boot stage of build. Therefore we should better use own IDL implementation to be able to generate interfaces' description from text files. I do not provide formal definition of language here - I hope that it's quite clear from the sample at http://web.firebirdsql.org/download/rabbits/alex/Interface.tgz . There are 4 files in it: 1. Interface.idl - description of our interfaces using IDL 2. Interface.h - c++ header (should be machine-generated from .idl, currently manually done) 3. implRefCounted.cpp - implementation of interface using that h-file 4. main.cpp - access to such interface We can use very simplified IDL version cause we do not care about host2host transfers of calls (i.e. all FB interfaces are local). Replacing of remote subsystem is not a goal here. So description of interface becomes very simple: interface IRefCounted : IVersioned { addRef(); int release(); }; where IRefCounted is it's name, IVersioned - name of base interface, and methods are provided after it in {} brackets. Any data types are accepted - we do not check for correctness (hmm, that may be a trouble when generating non-C++, but I hope it's solvable). I've also skipped 'void' before fundtion returning nothing to make language look more pascal-friendly, but this is not critical detail. What is generated from such description? I will not repeat here too much from Interface.h, just a plan of - what should be generated. Each interface is represented as c++ class with same name. For primary (non having base) interface (IVersioned in our case) generated some generic macros and a pointer to virtual table as 'void* IDL_vt'. The following is generated for all interfaces. struct VTable - it's based on base interface's VTable. As typical virtual table it contains pointers to functions, representing interface methods. Due to inheritance it actually contains functions for current interface and all the chain of base interfaces. Wrappers for calls in virtual table. I hope it's clear from the example what do they do, but I want to notice that calling that wrappers at c++ level is done in the exactly same way as is used currently in FB3. Also please take into an account that for methods, containing IStatus* as the first parameter, it's pretty easy to add check for an error after the call and throw an error in c++ style in machine-generated code therefore making actual code better. This is the end of interface description, but in the end of generated file we have one more section which helps to implement interface. There are implementation header and footer, use of them is clear from implRefCounted.cpp file in the sample. Each implementation begins with static virtual table which will be assigned to IDL_vt of all instances. After it implementations of functions used in this vtable follow - they are certainly static and call appropriate function of user's interface implementation (will be extended with try/catch for methods with IStatus*). I.e. if there is 'addRef()' method in the interface user MUST implement 'void addRef()' function when implementing an interface. Or he gets compile-time error. Next function for vtable initialization follows - it must be called in any user's constructor. In the footer of implementation there is a space for virtual table. And (pay attention) all this is under some simple #ifdefs. That ifdefs make implementation of interface very simple - one should define BEGIN_IMPLEMENT_IXXX macro as a name of implementation, next include generated h-file - and after it is free to write his own code to implement interface in traditional c++ way. In the end of interface implementation a trick use in the beginning is repeated with END_IMPLEMENT_IXXX macro. This is what is done in implRefCounted.cpp sample. Later access to such class has no specifics. Use of such interfaces is even simpler - you may see in main.cpp that it absolutely does not differ from well known samples of interface usage. As the result we get language-neutral compiler-independent ABI, with an ability to generate a kind of headers for any language, with a machine generated code to catch exceptions into status vector and raise them from it (if language supports certainly), with our own structure of virtual table and therefore absolutely stable and clear interface version upgrade and (as additional small bonus) we nned not count interface versions manually. Estimated time required to code idl2h converter is not more than a week. That program is not needed for end-users - only for one who want to build firebird from sources and/or take part in the development. If we agree with such form of API description I volunteer to write the program. ------------------------------------------------------------------------------ Infragistics Professional Build stunning WinForms apps today! Reboot your WinForms applications with our WinForms controls. Build a bridge from your legacy apps to the future. http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk Firebird-Devel mailing list, web interface at https://lists.sourceforge.net/lists/listinfo/firebird-devel