Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2002-11

Mapping Object Pascal Classes to C++ Classes

12 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Unknown author

Hi All,

I found an interesting articla written by Rudy Velthuis on the above subject. Take a look at:

http://home.t-online.de/home/rvelthuis/cppobjs.htm

It works in Delphi like a charm. Is this possible in FPC?? I don't have FPC to hand to test it out.

Try the following code: (NB. The c++ dll was compiled using Borland C++ 5.5.1, this may not work with gcc or other compilers..)

The C++ code is a little half-arsed btw, and uses stdio.h instead of iostreams.h for no good reason.

Matt

// C++ DLL
//Start
#include <stdio.h>
class AbstractTest
{
public:
   virtual void write(const char *text) = 0;
   virtual void writeLn(const char *text)= 0;
   virtual void free(void) = 0;
};
class TestClass: public AbstractTest
{
public:
   virtual void write(const char *text){ printf(text); };
   virtual void writeLn(const char *text){ printf(text, "\n"); };
   virtual void free(void){ delete this; };
};

#define EXTERN __declspec(dllexport) __stdcall

extern "C" AbstractTest* EXTERN NewConsole(void){

  return new TestClass();

}

#pragma argsused int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long \ reason, void* lpReserved) { return 1; }

//End
//Pascal Import Unit
//Start
unit testu;
interface
type
  TestClass = class
  private
    OldSelf: TObject;
  public
    procedure Write(text: PChar); virtual; cdecl; abstract;
    procedure WriteLn(text: PChar); virtual; cdecl; abstract;
    procedure Free; virtual; cdecl; abstract;
  end;
function NewConsole: TestClass; stdcall;
implementation

{ $l test.obj }

function NewConsole: TestClass; external 'Test.dll';
end.
//End
//Pascal console app
//start
{$APPTYPE CONSOLE}
uses
  SysUtils,
  testu in 'testu.pas';
var
  t: TestClass;
begin
  t := NewConsole;
  t.Write('hello ');
  t.WriteLn('there');
  readln;
end.
//End

---------------------------------------------
This message was sent using Mistral WebMail.
http://www.mistral.co.uk/

Reply by email

Florian Klaempfl
to Unknown author
you wrote 10 lines
Hi All, I found an interesting articla written by Rudy Velthuis on the above subject. Take a look at: http://home.t-online.de/home/rvelthuis/cppobjs.htm It works in Delphi like a charm. Is this possible in FPC?? I don't have FPC to hand to test it out.

I don't think so. I guess it works only because Borland C++ is used and Delphi and BC++ use the same
back end and probably a similiar VMT generation.

Further, these methods are limited: no multiple inheritance, no exceptions etc..
Its use depends on what you want to do.

Afaik you're one of the BeFPC people, right? If you want a clean mapping of the gui
classses from C++ to pascal, we can talk about C++ classes support in FPC 1.1. The question is whether it is possible, it depends on the involved C++ language features.

E.g. if exceptions are used, things get rather complicated. In this case I would suggest to modify h2pas to eat C++ and create wrappers as usual which do
the exception conversion.

Reply by email

Unknown author
I don't think so. I guess it works only because Borland C++ is used and Delphi and BC++ use the same back end and probably a similiar VMT generation.

I think it's the way Delphi is implemented. It also works when the DLL is compiled with MinGW, which certainly isn't Borland compatible in the same way as BC++ is. I just tested it. Further, the C++ class doesn't have to be abstract as Rudy suggests, because I altered it to return the 'TestClass' in my example, and it still works.

Further, these methods are limited: no multiple inheritance, no exceptions etc.. Its use depends on what you want to do.

If you write C++ reserving Multiple Inheritence for extremes, this shouldn't be a problem. However, in truth, you're right. Many C++ programmers get lost in the wonders of multiple inheritence. Surely Exceptions could be handled in some way? a simple mapping in the same manour, and some glue code to 'catch' the exception and pass it to Pascal if it is unhandled in C++.

Afaik you're one of the BeFPC people, right?

Yeah, except I'm on hiatus from that project. There are two French guys leading up at the moment, and they are wrapping the API directly with a different approach to that I started with. I want to wrap the API in a VCL/LCL style using a flattened universal API. This will get picked up at some point in the new year. The groundwork is there, but I have to make it more generic.

If you want a clean mapping of the gui classses from C++ to pascal, we can talk about C++ classes support in FPC 1.1. The question is whether it is possible, it depends on the involved C++ language features.

I think it would be cool if FPC does it on this level, with some 'behind the scenes' glue code to pad out the problems you've noted above. I think it works for Delphi because Borland altered the VMT to mimic that of C++ on the Windows platform to enable COM to work (For Delphi 2 before interfaces existed.)

E.g. if exceptions are used, things get rather complicated. In this case I would suggest to modify h2pas to eat C++ and create wrappers as usual which do the exception conversion.

The other guys have written a class mapper of sorts. I haven't really been keeping up with them. The only reason I stumbled onto this article was that I was looking into an automated C++ class flattener to help me use Muscle in Delphi (http://www.lcscanada.com/muscle/index.html). As muscle will compile using BC++ 5.5.1, I can probably map most of it using this technique. Supporting FPC would be cool too.

Anyway, with the new GCC3.x 'universal' ABI, shouldn't it all become a bit easier soon? :-)

Matt

---------------------------------------------
This message was sent using Mistral WebMail.
http://www.mistral.co.uk/

Reply by email

Unknown author
> I don't think so. I guess it works only because Borland C++ is used and > Delphi and BC++ use the same back end and probably a similiar VMT >generation.

It does not work with FPC 1.04. I just d/l and tried it with -Sd mode. Oh well ;-)

Matt

---------------------------------------------
This message was sent using Mistral WebMail.
http://www.mistral.co.uk/

Reply by email

Olivier Coursiere

Hi all,

> Afaik you're one of the BeFPC people, right? Yeah, except I'm on hiatus from that project. There are two French

guys leading

up at the moment, and they are wrapping the API directly with a

different

approach to that I started with. I want to wrap the API in a VCL/LCL

style

using a flattened universal API. This will get picked up at some point

in the

new year. The groundwork is there, but I have to make it more generic.

I am one of the french guys ;-)

The other guys have written a class mapper of sorts. I haven't really

been

keeping up with them.

In fact, the class mapper is not yet finished.
Our tool is an automated C++ class flattener, but it is specifically designed
for the C++ API of BeOS :

- no C++ exception
- no template
- few multi-inheritance
- support of hooks to answer to system events (optional and maybe a BeOS feature)

It should also work on other systems if your API respect the above requirements
(with some minor change i think).

We have a proof of concept tool that generate the C/C++ part of the glue code.
This tool is based on stubgen and is written in C.

Curently, i am writing a new tool (codegen) that will also generate the pascal part.

How it works :

codegen use a XML description of the header and a basic typmap file. It will generate pascal and C/C++ glue code.
It use the "flat" way, but it also generate a pascal class to wrap C functions
(each C++ classe will have a corresponding pascal one)

The XML description is generated with headertoxml. This tool use the stubgen parser in a shared object (stubgen.so). I pack stubgen in a shared object to write most of the code in pascal.

More informations (sources) at
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/befpc/bepascal/bepascal/ in those directories :

- codegen
- headertoxml
- stubgen
- stubgen.so

Supporting FPC would be cool too.

This is in my TODO's list too but i have no time yet because of the above project...

Reply by email

Unknown author

Ah, Olivier, you're 'here', that's cool ;-) The other guy is called Eric, for the record. I do know peoples names, honest ;-) I just glossed over the general project as I don't know who is doing what at the moment.

Show quoted text 15 lines
I am one of the french guys ;-) >The other guys have written a class mapper of sorts. I haven't really been >keeping up with them. In fact, the class mapper is not yet finished. Our tool is an automated C++ class flattener, but it is specifically designed for the C++ API of BeOS : - no C++ exception - no template - few multi-inheritance - support of hooks to answer to system events (optional and maybe a BeOS feature)

I had a wanted to use is myself for mapping Muscle classes to Pascal - for the uninformed, Muscle was originally written for BeOS, but now compiles on Win32, Linux and IIRC Solaris, amoungst others, and has a Java layer also. I found it wouldn't compile - probably type sizes etc. I did wonder why you used the K&R parameter syntax with in some of the C parts though ;-)

It should also work on other systems if your API respect the above requirements (with some minor change i think).

One day, when I get 5 minutes to let the dust settle, I am goint to write a class flattener in C/C++. It will supply flattened API, just as Florian suggested.

However, I think for BeOS I have another solution. I'm not saying too much, but I think I can hack out a generic wrapping method. Watch this space :-) (hint: BeOS, on all platforms, mangles the method names in a completely regular way. The ABI is never going to change as BeOS is effectively a closed source, 'final' platform.)

This is in my TODO's list too but i have no time yet because of the above project...

Olivier, I think I will handle this (as above) because I have some ideas I want to try out.

Matt

---------------------------------------------
This message was sent using Mistral WebMail.
http://www.mistral.co.uk/

Reply by email

Florian Klaempfl
to Unknown author: I think it's the way Delphi is implemented. It also works when the DLL is compiled with…
you wrote 10 lines
> I don't think so. I guess it works only because Borland C++ is used and > Delphi and BC++ use the same back end and probably a similiar VMT generation. I think it's the way Delphi is implemented. It also works when the DLL is compiled with MinGW, which certainly isn't Borland compatible in the same way as BC++ is. I just tested it. Further, the C++ class doesn't have to be abstract as Rudy suggests, because I altered it to return the 'TestClass' in my example, and it still works.

Hmmm, if I find time I'll look into it :/

Show quoted text 5 lines
> Afaik you're one of the BeFPC people, right? Yeah, except I'm on hiatus from that project. There are two French guys leading up at the moment, and they are wrapping the API directly with a different approach to that I started with. I want to wrap the API in a VCL/LCL style

BeOS support for the LCL :) ?

Anyway, with the new GCC3.x 'universal' ABI, shouldn't it all become a bit easier soon? :-)

Yepp, but when we implement this, the GCC3 must be stabilized first.

Reply by email

Unknown author
Show quoted text 5 lines
>I think it's the way Delphi is implemented. It also works when the DLL is >compiled with MinGW, which certainly isn't Borland compatible in the same way >as BC++ is. I just tested it. Further, the C++ class doesn't have to be >abstract as Rudy suggests, because I altered it to return the 'TestClass' >in my example, and it still works.

You can actually do what you like to the Delphi side, and Delphi doesn't seem to worry. If you alter the order of the virtual methods on C++, the Delphi side will call the wrong method. It's not doing anything clever, it is litterally mapping the VMT directly on to the C++ VMT. I think the FPC problem is possibly because FPC either doesn't do the Delphi 'hack' Rudy mentions - moving all virtual methods from TObject into a negative offset when compared to the start of the VMT as the instance sees it, or maybe the VMT just isn't compatible. Remember this is just in Delphi 5... I'm wondering if Delphi 4 or 6 will have such a success.

Hmmm, if I find time I'll look into it :/

If you could generate Delphi compatible VMT, would that enable FPC classes to be compiled and used by Delphi, if there was a common Object format. Okay, I know DCU is a bit of a non standard, but supporting some kind of DLL based solution could be cool.

If you could get the direct VMT mapping working, extending the ObjFPC mode to include a CPPClass as well as Class would be cool. The compiler does the gruntwork, so long as the special C++ format is followed...

BeOS support for the LCL :) ?

Yeah. That is what I want. The others, Olivier especially, are mapping Pascal Classes to C++ Classes of the BeAPI. Whilst this helps people who program in BeOS already, it is a bit of a non starter for those who want to use a VCL alike. I think there is room for both approaches though, which is why we joined together in the first place.

>Anyway, with the new GCC3.x 'universal' ABI, shouldn't it all become a bit >easier soon? :-) Yepp, but when we implement this, the GCC3 must be stabilized first.

See you sometime in 2010 then ;-)

Matt

---------------------------------------------
This message was sent using Mistral WebMail.
http://www.mistral.co.uk/

Reply by email

Ramon Bosque
to Unknown author: Ah, Olivier, you're 'here', that's cool ;-) The other guy is called Eric, for the record.…

Mensaje citado por:

Show quoted text 16 lines
One day, when I get 5 minutes to let the dust settle, I am goint to write a class flattener in C/C++. It will supply flattened API, just as Florian suggested. However, I think for BeOS I have another solution. I'm not saying too much, but I think I can hack out a generic wrapping method. Watch this space :-) (hint: BeOS, on all platforms, mangles the method names in a completely regular way. The ABI is never going to change as BeOS is effectively a closed source, 'final' platform.) Matt

And what will it happen with the open source substitutes for BeOS (in particular OpenBeos, which is not based on Linux)?

Best regards

Ramon Bosque

Reply by email

Unknown author
And what will it happen with the open source substitutes for BeOS (in particular OpenBeos, which is not based on Linux

Open BeOS R1 will be based on the current BeOS R5.03 base. It will almost be an upgrade, rather than a new OS. It replaces key components one by one. Gcc will stay the same, plus they should support the old API wherever possible because it aims to be backwardly compatible. Okay at some point they will break compatibility, but then the Amiga port is probably not going to run well on the Amiga One platform or Amiga OS 4 that is targetted to the PowerPC.

Matt

---------------------------------------------
This message was sent using Mistral WebMail.
http://www.mistral.co.uk/

Reply by email

Olivier Coursiere

Hi all,

I had a wanted to use is myself for mapping Muscle

classes to

Pascal - for the uninformed, Muscle was originally written for BeOS,

but now

compiles on Win32, Linux and IIRC Solaris, amoungst others, and has a

Java

layer also. I found it wouldn't compile - probably type sizes etc. I

did wonder

why you used the K&R parameter syntax with in some of the C parts

though ;-)

I don't use K&R parameter syntax. The original tool use it. Look at the readme file of stubgen.
My changes are only in the print_function. But i am not really a fluent C programmer. That's why
i start codegen. string manipulations are easier in pascal than in C (from my point of view).

> It should also work on other systems if your API respect the above > requirements (with some minor change i think). One day, when I get 5 minutes to let the dust settle, I am goint to

write a

class flattener in C/C++. It will supply flattened API, just as

Florian

suggested. However, I think for BeOS I have another solution. I'm not saying too

much, but

I think I can hack out a generic wrapping method. Watch this space :-)

(hint:

BeOS, on all platforms, mangles the method names in a completely

regular way.

The ABI is never going to change as BeOS is effectively a closed source, 'final' platform.)

Good luck to find docs !

> This is in my TODO's list too but i have no time yet because of the > above project... Olivier, I think I will handle this (as above) because I have some

ideas I want

to try out.

Ok !

Reply by email

Unknown author
Good luck to find docs !

It's all in the BeBook. Methods are 'flattened' by C++ using the same ABI over the whole of BeOS (R4+ for Interl and DR8+ for PowerPC).

OBOS will use the same ABI, simply because they want backwards compatibility at a binary level. B.E.OS, who knows, or cares ;-)

Matt

---------------------------------------------
This message was sent using Mistral WebMail.
http://www.mistral.co.uk/

Reply by email