[KDE Dot News]
 faq
 flatforty
 contribute
 subscribe
 configure
 search
 rdf

 main
 parent
 thread


Re: Cool
by Ivan Deras on Friday 24/Sep/2004, @13:20
When you want to write bindings to C++ libraries it's always neccesary to make a intermediate library in C to convert it to a plain API (CLX for Example, need Pascal bindings for QT), and this way isn't beautiful for me, although QT library in elegantly implemented in C++.
  Related Links
 ·   Articles on Qt
 ·   Also by Ivan Deras
 ·   Contact author

Thread Threshold:

The Fine Print: The following comments are owned by whomever posted them.
( Reply )

Re: Cool
by Roberto Alsina on Friday 24/Sep/2004, @14:25
Not if you are using something like Smoke.
[ Reply To This | View ]
Re: Cool
by Andreas Hausladen on Friday 24/Sep/2004, @14:31
The problem with bindings is the ABI not C++ itself. Name mangling, virtual (method) table structure, memory alignment and calling conventions are the main issues that must be solved for a working binding. And who known better about these ABI things than the compiler for the API itself. So instead of finding out how to map the C++ ABI to Delphi' ABI and invest additional time when a new gcc is released (gcc had a really inconsitent ABI in the past), you "simply" write a C wrapper shared object in C++ and recompile this when gcc has changed.

It is possible to map the C++ ABI of gcc 2.95 to Delphi and it is possible to map the ABI of gcc 3.1 to Delphi ABI.
Name mangling can be resolved by Delphi's shared object import concept "function name(parameter): RetType; cdecl; external soName name 'symbol';" plus the c++filt utility.
VMT mapping works as long as the base class has a virtual method declared before a field, so the C++'s VT pointer is at offset 0. (QObject works perfectly). Otherwise you must use the obsolute "object" keyword (from TurboPascal days). It is the corresponding type for C++'s "class" keyword, but it is obsolute and said to have many bugs (I never found one).
For gcc 2.95 you must declare two dummy virtual methods to move the VMT offset of the first real virtual method 8 Bytes down.
For gcc 3.x the dummy method is not necessary (and would lead to wrong calls)
Memory alignment is no problem at all. With Delphi you can adjust it {$ALIGN 4}
And the calling convention is furtunatelly the "cdecl" one.

But even if you implement all this (it works, I have tested it last year with QObject and QWidget) two issues remain:
1. What is with inlined methods/functions, they are not exported by the shared object. You must find them and reimplement them in Delphi by hand. And C++ programmers tend to use many inline function (at least Qt has lots of them)
2. What is with templates? Templates are always inlined. They are not possible in Delphi except you write all template specializations by hand. Qt does not have that many (what about Qt4 ?) but eight or more are even too many to keep in sync with newer Qt versions.


So you see it is possible with limitations. The perfect solution would be a very small C wrapper (templates?, inline functions) and a native ABI map. But when you already have a C wrapper why not add all things to the wrapper and simply use a C interface from the binding language to the C++ code.

If there would be a common ABI all these issues would not exist. .NET for example has such a common ABI. The intermmediat language is designed to support more than one programming language. That's the reason why beside C# there are also VB#, Delphi.NET, ...

I wish gcc would export an additional "common ABI" for classes and templates like joliet is for iso9660. It is additional but if you cannot read it you can use the "old" one (ok the comparision is not good). Another example is COM under Windows. You can use it in C++, VB, Delphi and even in all .NET languages. And if that "common ABI" would be controllable by a class modifier that would be really great. For example: Q_EXPORT __commonabi class MyClass {} In this case gcc would create a function pointer table for all non-private methods.

struct CommonAbiClass
{
char* name;
CommonAbiClass* bases; // array
CommonAbiItem* methods; // array
void* reserved; // for future extensions
};

struct CommonAbiFuncItem
{
void* myfunc;
char* name;
paramItem** params;
type retType;
void* reserved; // for future extensions
};

And as fields should not be accessed directly all could be handled through these function pointer tables. And you would have an included RTTI for each public and protected method. Even bindings could be generated without the source code.

I'm dreaming, I know.



Regards,

Andreas Hausladen
[ Reply To This | View ]
  • Re: Cool
    by Richard Dale on Saturday 25/Sep/2004, @11:57
    You have some interesting ideas here, but it is all very compiler specific and so a practical binding could never be implemented this way. Also how do override C++ virtual methods in a Pascal class using this sort of technique? To me it looks like it only solves the problem of calling C++ methods from Pascal and not callbacks for virtual methods or slot invocations going the other way.
    [ Reply To This | View ]
    • Re: Cool
      by Andreas Hausladen on Saturday 25/Sep/2004, @14:16
      I have a working Pascal binding (http://tinyurl.com/55cd9) with signal/slot support and virtual method overriding.


      The "common ABI" could have (as generated by the compiler itself) an additional void** for virtual methods that point to the virtual table entry.


      > but it is all very compiler specific and so a practical binding
      > could never be implemented this way.

      That's why I wrote: "I'm dreaming."
      [ Reply To This | View ]
      • Re: Cool
        by Richard Dale on Sunday 26/Sep/2004, @01:09
        Well I looked at the .png.

        But then I see you're working on Qt#/Bugtussle, and I've been fishing around looking at those docs - interesting. I hadn't heard of it until Adam Treat mentioned it in his blog a few weeks ago. I hope by KDE 3.4 at least one of the three(!) C# bindings projects succeeds in wrapping the KDE api. There will be a lot more people interested in a C# binding than Pascal I would have thought.

        I haven't done anything on my Kimono C# project for a while, because I've been too busy with ruby. And I really ought to spend some time getting the KDE java bindings improved a bit - so I'm not sure if I'll have come up with anything worthwhile by KDE 3.4. I don't think multiple C# bindings implementations are a problem, but it might be a good idea to ensure they are source code compatible if that was possible. Then a C#/KDE app written with one variant would compile and run with the other two..
        [ Reply To This | View ]
        • Re: Cool
          by Andreas Hausladen on Sunday 26/Sep/2004, @04:38
          > I hope by KDE 3.4 at least one of the three(!) C# bindings projects succeeds in wrapping
          > the KDE api. There will be a lot more people interested in a C# binding than Pascal I
          > would have thought.

          When Adam is back we start to mix Bugtussle with Binge. Bugtussle is good in reading the doxygen XML files and Binge is good in writing C# bindings.
          But at the moment I'm writing a C++Parser in C# to remove doxygen dependencies. Doxygen is a documentation tool and as such it is not really a good base for writing bindings. And the lastest doxygen makes template generation impossible because the xml base class entities lost the template parameters.
          QByteArray derives now from QMemArray instead of QMemArray<char>.
          And I'm not in the mood to rewrite the APILoader code every time doxygen changes.
          [ Reply To This | View ]
Re: Cool
by ac on Friday 24/Sep/2004, @14:39
NO! It's NOT! These are lies perpetuated by people with language agendas (e.g. GNOME trolls) Look at libfam and look at all manner of languages and environments using it even though it's implemented in C++.

http://oss.sgi.com/projects/fam/
[ Reply To This | View ]
  • Re: Cool
    by ca on Saturday 25/Sep/2004, @23:28
    FAM exports a C interface, not C++.

    Language agendas? If anything, people like you have language agendas and deserve to be called trolls. There are GTK/GNOME apps out there that are written in C++, or Python, or whatever. They don't say "C++ sucks", they provide bindings for many languages. On the other hand, people like you say "C sucks, I don't care what legitimate reason you have to use C, you are an idiot for using C".
    [ Reply To This | View ]
    • Re: Cool
      by ac on Sunday 26/Sep/2004, @07:20
      > FAM exports a C interface, not C++.

      Exactly. Keyword: exports. Implemented in C++. Now I hope next time you can hold an informed conversation instead of making stupid statements against C++.

      > "C sucks, I don't care what legitimate reason you have to use C, you are an idiot for using C".

      It's not me saying this. It's the GNOME camp that's saying this. What do you think Mono is? People over there are fed up with C. I don't give a damn about how you feel about C, it's irrelevant.
      [ Reply To This | View ]
Re: Cool
by M on Friday 24/Sep/2004, @15:28
While it is still better to write the library in C++ and provide some simple C wrapper if a binding is really needed. Just look at QtC, its not so hard and you only need to wrap up the public API.
Many languages don't need bindings for C++ as there is already some compiler technology to mix them. C++, objC, Java can be mixed to some extent with gcc for instance.
[ Reply To This | View ]
  • Re: Cool
    by Richard Dale on Saturday 25/Sep/2004, @11:32
    "Just look at QtC, its not so hard and you only need to wrap up the public API.
    Many languages don't need bindings for C++ as there is already some compiler technology to mix them."

    The QtC library has been retired and replaced by Smoke. It's not true that just because gcc supports java or Objective-C you don't need bindings for them.

    "its not so hard and you only need to wrap up the public API"

    Umm, I would like to say language bindings are easy, but they're not. Ashley Winter's Smoke library design is one of the most innovative things in KDE in my opinion. A long, long way ahead of what I managed with my first attempts at language bindings with QtC (as part of the effort to implement Objective-C bindings).
    [ Reply To This | View ]
Re: Cool
by L505 on Friday 28/Apr/2006, @17:50
You could also use Fake Objects using C Structs or Pascal Records.
Looks a bit messier than true OO code but it works. The balance between OO and procedural code, while still having the power to export from a library. Messier than OO but cooler than OO :-)

I've attached a file which shows an example of a Pascal code with a few Fake Objects using plain records. Private data in the fake object is accessible if you want to shoot your foot, but is labelled very clearly using _private. Similar things have been done in the C language using _private or private_.

Call me messy but this was just a little experiment of mine. Note how I fake "self". Objects have a self available and in order to make "self" available using records/structs, you must pass a dummy Self parameter throughout some of the functions.

The example file attached shows how to use a Pointer to a record or a regular record without being a pointer. See FakeObject versus TRecord in the attached file. EXE demo is included on win32 - I'll make a linux elf some time later.

This example was done in delphi but should be easily compiled in FPC too. CompactUtils uses true objects, ignore that - the fakeobject examples are in the FakeObject directory.
Click to download attachment FakeObject.zip
85KB (87645 bytes)

[ Reply To This | View ]
The Fine Print: The previous comments are owned by whomever posted them.
( Reply )

  "coffee? kde developers drink tea ;)" -- Dirk Mueller
KDE®, "K Desktop Environment", "KDE Dot News", "got the dot?" and the KDE Logo® are trademarks or registered trademarks of KDE e.V. in the European Union, the United States and other countries. All other trademarks and copyrights on this page are owned by their respective owners. Comments are owned by the poster. The rest: Copyright © 2000-2008 KDE e.V. for The KDE Project. For further information or comments on this site, please contact the Webmaster.
[ home | post article | flat forty | subscribe | search | rdf ]