The simple answer is that you cannot reliably mix object oriented
langugages without severe portability issues and without loosing basic
functionality: polymorphism. You simply cannot extend the functionality of
a class written in one language from another language.
ON THE LINKING PART: all that distinguishes a member function from a usual
one is that a member function has an implicit first argument which is a
pointer to the class instance. So, you can put all your member functions
in a dll, and from an assembly level view point they are just regular
function with an additional first argument (pointer to the class instence
- *this in c++, self in o-pascal). How the calling language interprets
them is a matter of the calling language.
The problem is the logical structure of a class. That is, the layout of
the VMT, and stuff like this. Generally, the pointer to the first virtual
method is at offset 0, so you can safely call virtual functions from a
single inherited C++ class. However, everything else is different. For
example, different versions of delphi place the automated methods at a
different offset, etc. The simplest problem is the destrictor. All delphi
classes have the destructor at offset -4. A C++ class CANNOT have a
virtual destructor (the VMT is killed when you call delete, before the
class' destructor is called). In fact, C++ classes need not have a VMT at
all.
So if the function calls virtual methods, the dll that contains that
function MUST use the internal representation of a class as the calling
program (which supplies *this, e.g. Self). This will force you to use the
same object model as C++. Since C++ does not support class functions for
example, I don't see how you can mix a delphi function in a dll with
C++ code. A C++ class need not have a VMT at all. If a C++ member function
belongs to a Multiple Inheritance class then this class will have several
VMTs, so the whole thing becomes pointless. You cannot ensure any code
portability. So linking is not the problem.
If you want to use class libraries, you have to make this class library
into a reasonable API with reasonable semantics, behavior and so on. An
example is the way QT is interfaced with Kylix. It works, only because QT
is reasonably well written, all the new/deletes of QT objects are
explicitly wrapped in Kylix, and the published QT member functions don't
do weird things. All QT functions are wrapped as normal function, by
explictly specifying the Self pointer as the first argument. The last
problem in this is the actual linking. In fact the unofficial QT patches
(QT 3) does the same thing using object semantics on the Kylix side. It
works, because QT is a reasonable API, and obviously, you cannot extend QT
in any way.
I don't know what FPC does with member functions, but Delphi does not
export them. You cannot put a member function in the export part of a
library. You have to create a wrapper (normal function with Self as the
first argument) and then export the wrapper. So, if you happen to have a
good class API in Delphi, you have to manually type wrappers and export
them. This can be changed in FPC by allowing TMyObject.MyFunction in the
export part of a library.
Peter
On Mon, 22 Jan 2007 13:17:48 -0600, Felipe Monteiro de Carvalho
<[EMAIL PROTECTED]> wrote:
Hello,
I was studing how to write the system unit for Symbian OS, and
everything on Symbian is C++, so you actually import lot´s of methods
from classes, not procedures. So I decided to study the task of
linking from Free Pascal to C++
Maybe it´s easy to be implemented, and that would be very nice. Here is
my test:
To start with I created a trivial C++ DLL:
File: cpplib.cpp
class User
{
public:
__declspec(dllexport) int Sum(int a, int b);
};
int User::Sum(int a, int b)
{
return a + b;
}
File: build.bat
PATH=C:\Programas\Dev-Cpp\bin
g++ -c cpplib.cpp -o cpplib.o
dllwrap.exe --output-def cpplib.def --driver-name c++ --implib
cpplib.a cpplib.o -L"c:/Programas/dev-cpp/lib" --no-export-all-symbols
--add-stdcall-alias -o cpplib.dll
Calling build.bat will of course produce cpplib.dll It also produces a
cpplib.def
Now, I utilized dllview software I created and saw that cpplib exports
this function: _ZN4User3SumEii
Then, I created a simple pascal software to call that function:
program loadcpp;
{$mode objfpc}{$H+}
{$apptype console}
uses
SysUtils, ctypes;
function User_Sum(Self: Pointer; a, b: cint): cint; cdecl; external
'cpplib.dll' name '_ZN4User3SumEii';
begin
WriteLn('7 + 8 = ' + IntToStr(User_Sum(nil, 7, 8)));
end.
And it works!
So, basically, what I mean with this is: What is needed to add C++
linking to Free Pascal? It seams to me that it should be easy, we just
need to understand C++ name mangling and choose a sintax to implement
it. Maybe something like this:
type
User = class
public:
function Sum(a, b: cint): cint; cdecl; external 'cpplib.dll';
cpp_name_mangling;
end;
One possible problem is C++ multiple inheritance. I would propose
that, to start with, just disconsider it.
Disclaimer: I know very little on the subject, so feel free to correct
me =)
thanks,
|***********************************************|
_______________________________________________
fpc-devel maillist - fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel