faq
flatforty
contribute
subscribe
configure
search
rdf
main
parent
thread
|
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 |
|
|
The Fine Print: The following comments
are owned by whomever posted them.
( Reply )
|
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 ]
|
|
The Fine Print: The previous
comments are owned by whomever posted them.
( Reply )
|
|