MonSiteWikiNi

DeeWrapperGenerator

PagePrincipale :: DerniersChangements :: DerniersCommentaires :: ParametresUtilisateur :: Vous êtes ec2-3-19-31-73.us-east-2.compute.amazonaws.com

Translation


The dee wrapper generator I wrote had french comments in one of its file header. Here is the translation.

todo = """
+-- Correct enums handling
+-- alias byte uchar ;
+-- Beware the callbacks in the properties. Improvement needed.
+-- Methods/functions returning callback functions :
    void (* func )( int , int , int , int , Fl_Color ) Fl_get_boxtype ( Fl_Boxtype arg0 ) {
        return Fl::get_boxtype ( arg0  );
    }
    The above code is incorrect, it has to be replaced by the following :

    void (* Fl_get_boxtype ( Fl_Boxtype arg0 ))( int , int , int , int , Fl_Color ) {
        return Fl::get_boxtype ( arg0  );
    }

+-- callbacks (FunctionType):
    o--In the c_str methods : fix the code generation in the functions ( doing something like the Method class ).
    +-- In the d_str and d_import functions : remove the pointer star after : return function ( args ) __*__.
""'

done = """
+-- Why is there a trailing comma after the last parameter of some Constructors ?

+-- Functions : Avoid the & ( adress of ) for return types that are not references.

+-- Make a symbol table. No more use findNode (). Add a __getitem__ function in 
    self.root ( 'GCC_XML' ).
    Keep handleClasses. It allows to avoid inclusion of not implemented nodes. 
    > Use it to add each attribute of a class -> 'members'.
    > Will be much more efficient and less complicated than handleClasses.

+-- D Wrapper classes : dereference the D wrapper parameters {Class, Struct, Union } with the
    .ptr () method in the constructor, functions et check if it's not needed for methods.

+-- Extends the use of dereferencing method .ptr () for structures and unions.

+-- Passing parameters by reference : simulate it giving C++ pointer that can be manipulated in D.
    This method/functions uses dereferencing for its argument :
        void Classname_method ( Classname * self, OtherClass * ref ) {
            self->method ( *ref );
        }

+-- D references and C++ pointers : Structures, Unions.
    If a function returns a pointer on a class instance, that instance  must be transformed into a D reference.

+-- Use isinstance () instead of __class__.

+-- Make a command line incerface for the analyse.py script to use it on some C++ samples.

+-- Take into account the static fields (Field class). -> They are 'Variable'.

+-- Don't generate a "by pointer" constructor with a default '= null' argument if it 
    already exists a constructor without argument.

+-- Why the 'char *' is transformed into a 'char' ?  -> PointerType.d_import (). Fixed.

+-- There is a segmentation fault when we use a subclass destructor
    prior to the base class one. Even if we test the value of the self pointer in the base class,
    the seg fault remains. The solution is no to define the destructor in subclass
    to use only the base class one. As everything is made by pointer, the C++ part
    knows wich destructor to call.

+-- Don't redefine the 'self' pointer ( to the C++ instance ) if there is a base class.

+-- Public members and other than  methods and {cons,des}structors must be generated as
    D properties:
    Field.c_str () -> <field.type> <field.name>_get ();
                   -> void <field.name>_get ( <field.type> );

    Field.d_str () -> <field.type> <field.name> ();
                   -> void <field.name> ( <field.type> );

+-- In the d_import () constructors : fix the generation of arguments and return type Class.
    Do it in the destructors too.

+-- Typedef management in d_import () functions: generate the name, not the definition.

+-- D references and C++ pointers :
    If a function returns a pointer to a class, it has to be transformed into a D reference.
    Add a constructor by pointer in the D classes.

+-- Static methods management in c_str () function : there must not be a self pointer.

+-- C++ functions export : give them a different name in C ( starting with a '_' )
    to avoid a double definition and allow the exportation to D.
    Redefine the original name in the import D file with an alias.

+-- Callbacks code generation problem fixed.

+-- Respect the '__const__ char *' attributes.

+-- D classes code generation:
    Make a symbol table.
    Classes are added method if there 'incomplete' attribute is set to 1.
    Avoid double definition of classes.
    |
    +-- Generalize it to other class members.
"""


Some comments about this generator


The good points about my D wrapper generator
It does what it is supposed to do : mainly wrapping C++ interfaces ( without templates inside it ) and generating the D interface using only the C++
sources. Compared to Swig, it is easier to wrap a C++ interface with my wrapper. Moreover, it has a good support for callback functions, simpler than the one provided by Swig. It also exports public attributes to D properties. This make programming in D nearly as natural as in the C++ version of the wrapped library. I've managed to port a subset of the FLTK library that seems to confirm the previous arguments.

The bad points about it
I no longer work on it. The code is too much spaghetti code. I thought it was because of some aspects scattered all over the code, but it is more about a bad design. I have used a Visitor pattern. Each node generates the code for its data and delegates the code generation it can't handle to its subnodes. That simply means that code for handling non trivial pointers policies will be scattered all over the nodes, thus the classes and their methods, that will have to deal with pointer attributes or parameters.

It uses gccxml : this tool seems to be no longer developped. I no longer manage to compile it, thus I can't use it to improve the wrapper generator.
It uses Python. Althought Python is a great dynamic programming language, someone coming from C++ who would like to switch to D but still use its
C++ code, has to download and install D, Python and gccxml. Looking back at it, this look pretty heavy. This can be even worse for someone coming from Java: he has to deal with C++, D, Python and gccxml.
Moreover if that wrapper had been successfull up to be THE C++ wrapper tool, it would have been difficult to ship it into the D distribution archive.

Conclusion
Gregor Richards has made a similar tool, BCD: http://www.dsource.org/projects/bcd, that do even more than mine. BCD uses gccxml output to generate D binding for C++, just like I wanted and it is written in D, that make it THE tool to choose to wrap C++ code to D.
Yet, it uses gccxml. Relying on a tool that doesn't compile on my platform, and I suppose others, a tool that does seem to be no longer supported,
is not a good idea, in my opinion. So, what should we do ?

Eric Anderton's Enki, http://www.dsources.org/projects/ddl/enki, is a parser generator that seems not too far from the ideas of the language machine, by Peri Hankey http://languagemachine.sourceforge.net, from what I have seen so far. It generates D parser. I think that one ( e.g. me if I manage my time reasonably well ) could write a parser for a subset of C++ that would output an analysis tree to be explored by a binding generator, or make a D front end for BCD.

That way, we could obtain a binding tool written in D, and lightweight enough to be shipped in the D distribution along with the compiler and
documentation tools. It would be less scary for C++ users to switch to D.
Il n'y a pas de commentaire sur cette page. [Afficher commentaires/formulaire]