Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/Database/DataSnap    [ Add a report in this area ]  
Report #:  104346   Status: Closed
Object Marshaling does not work in C++Builder
Project:  C++Builder Build #:  16.0.4429.46931
Version:    16.4 Submitted By:   jerome merignac
Report Type:  Crash / Data loss / Total failure Date Reported:  3/22/2012 3:34:18 AM
Severity:    Critical / Show Stopper Last Updated: 6/8/2012 8:16:04 PM
Platform:    All versions Internal Tracking #:   27111
Resolution: Duplicate (Resolution Comments) Resolved in Build: : None
Duplicate of:  79481
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: 8
Description
The simple marshaling object doesn't work correctly in C++Builder.
It's works fine in Delphi, but not in C++Builder.

1. I have build a DataSnap REST server.

2. I have create un simple object
class TUser : public TObject
{
private:
  String    FNom;
  String    FPrenom;
public:
  __fastcall TUser() {;}
__published:
  __property String Nom = { read=FNom, write=FNom };
  __property String Prenom = { read=FPrenom, write=FPrenom };
};

3. I add a published method to the datasnap server which returns a JSONValue, but the Marshal doesn't work, the fields are empty.

TJSONValue* TServerMethods1::GetUser()
{
   TJSONValue *jsonValue = NULL;
   TJSONMarshal *marshal = new TJSONMarshal();
   TUser *user = new TUser();
   user->Nom = "Nom";
   user->Prenom = "Prenom";

   jsonValue = marshal->Marshal(user);
   return jsonValue;
}


4. Start the server and open the navigator. Click the server functions link and test the method TServerMethods1.GetUser.
The result in navigator is empty in fields.
Why??????????????
Steps to Reproduce:
1. Create a DataSnap REST server in C++Builder.

2. In ServerMethodsUnit1.h, add a simple object TUser
class TUser : public TObject
{
private:
  String    FNom;
  String    FPrenom;
public:
  __fastcall TUser() {;}
__published:
  __property String Nom = { read=FNom, write=FNom };
  __property String Prenom = { read=FPrenom, write=FPrenom };
};

3. In ServerMethodUnit, add a public method : GetUser which returns a TJSONValue*.
TJSONValue* TServerMethods1::GetUser()
{
  CodeSite->EnterMethod("GetUser");
   TJSONValue *jsonValue = NULL;
   TJSONMarshal *marshal = new TJSONMarshal();
   TUser *user = new TUser();
   user->Nom = "Nom";
   user->Prenom = "Prenom";

   jsonValue = marshal->Marshal(user);
   CodeSite->Send(jsonValue->ToString());
  CodeSite->ExitMethod("GetUser");
   return jsonValue;
}

4, Start the server and open the navigator. Click the server functions link and test the method TServerMethods1.GetUser.
The result in navigator is empty in fields????????????????
Why??????????????

It's works fine in Delphi, but not in C++Builder.
Workarounds
None
Attachment
MarshallServer.zip
Comments

Tomohiro Takahashi at 3/22/2012 1:02:19 PM -
> Version: 16.4
> Build No: 1
What version(and Build No) of C++Builder do you use, for exmaple C++Builder XE2 Update 4(16.0.4429.46931)?

Tomohiro Takahashi at 3/22/2012 1:32:24 PM -
I confirmed this issue with C++Builder XE2 Update 4(16.0.4429.46931).
Thanks.

Tomohiro Takahashi at 3/22/2012 2:04:42 PM -
As a possible workaround, please use Delphi class instead.

1. create new Delphi unit as below
[User.pas]
----------------
unit User;

interface

type
  TUser = class
  private
    FNom: string;
    FPrenom: string;
  published
    property Nom: string read FNom write FNom;
    property Prenom: string read FPrenom write FPrenom;
  end;

implementation

end.
----------------

2. add User.pas to your project

3. remove TUser class definition for C++ from ServerMethodsUnit1.h

4. add #include "User.hpp" to ServerMethodsUnit1.cpp as below.
----------------
#include "User.hpp"
TJSONValue* TServerMethods1::GetUser()
{
   TJSONValue* jsonValue = NULL;
   TJSONMarshal *marshal = new TJSONMarshal();
   TUser *user = new TUser();
   user->Nom = L"Nom";
   user->Prenom = L"Prenom";
   jsonValue = marshal->Marshal(user);
   delete user;
   return jsonValue;
}
----------------

jerome merignac at 3/22/2012 8:48:37 PM -
I confirm the version C++Builder XE2 Update 4 (16.0.4429.46931).

Yes we saw the opportunity to go through Delphi objects but this is not a viable option for us because we already have all objects in C + + and we do not have a delphi license.

This problem is corrected you will for a future release or not?

Tomohiro Takahashi at 3/22/2012 10:51:56 PM -
> ... we do not have a delphi license.
AFAIK, C++Builder can compile Delphi .pas file. Could you please try my step?

Tomohiro Takahashi at 4/9/2012 6:25:10 AM -
This report was opened with valid Internal Tracking Number.
Thanks.

Luis Branca at 4/26/2012 6:17:16 AM -
Seems related to QC79481.
Check discussion on https://forums.embarcadero.com/thread.jspa?threadID=70904&tstart=0

Moritz Beutel at 6/8/2012 9:05:15 AM -
I think this is a test case error. As Takahashi-san said in the comments of QC #79481, you must explicitly enable RTTI by passing "--xrtti" to the compiler (you can add it to the project options as "additional options to pass to the compiler"), or alternatively by using the following statement in your source file:
// -----
#pragma explicit_rtti \
    methods (__published, public) \
    properties (__published, public) \
    fields(__published, public, protected, private)
// -----

Other than the --xrtti switch (which has the same effect), this is well
documented:
http://docwiki.embarcadero.com/RADStudio/en/Pragma_explicit_rtti

Server Response from: ETNACODE01