Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/Compiler/C++/Front End/RTTI    [ Add a report in this area ]  
Report #:  106268   Status: Closed
JSON marshalling incomplete in C++
Project:  C++Builder Build #:  16.0.4504.48759
Version:    16.4 Submitted By:   Luis Branca
Report Type:  Basic functionality failure Date Reported:  6/8/2012 2:13:55 AM
Severity:    Commonly encountered problem Last Updated: 6/8/2012 8:08:55 PM
Platform:    All versions Internal Tracking #:  
Resolution: Test Case Error (Resolution Comments) Resolved in Build: : None
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: 10
Description
Class fields not retrievable through RTTI in C++ as in Delphi.

On project options, C++ Compiler,  Enable RTTI is true.
Steps to Reproduce:
#include <DBXJSONReflect.hpp>
#include <memory>

class __declspec(delphirtti) TKid : public TPersistent {
  public:
  __fastcall TKid() : TPersistent() {};
    String FFirstName, FLastName;
    int FAge;
  __published:
    __property String FirstName = { read = FFirstName, write = FFirstName };
    __property String LastName  = { read = FLastName,  write = FLastName  };
    __property int Age          = { read = FAge,       write = FAge       };
};

void FooCppMarshall()
{
  std::unique_ptr<TKid>Kid(new TKid);
  Kid->FirstName = "Daniele";
  Kid->LastName = "Teti";
  Kid->Age = 29;

  std::unique_ptr<TJSONMarshal>Mar(new TJSONMarshal());
  std::unique_ptr<TJSONObject>SerializedKid
    (static_cast<TJSONObject*>(Mar->Marshal(Kid.get())));
  
   ShowMessage(SerializedKid->ToString()); // >>> The issue <<<
  // Shows: {"type":"Unit9.TKid","id":1,"fields":{}}
  // Should show: {"type":"Unit9.TKid","id":1,"fields":{"FirstName":"Daniele","LastName":"Teti","Age":29}}


  // On CB, ToString() call returns:
  //   {"type":"Unit9.TKid","id":1,"fields":{}}

  // On Delphi, ToString() call returns:
  //  {"type":"Unit9.TKid","id":1,"fields":{"FirstName":"Daniele","LastName":"Teti","Age":29}}
/*
References:
  http://www.danieleteti.it/?p=146 [Daniel Teti's blog]
  http://docwiki.embarcadero.com/CodeSamples/en/Declspec(delphirtti)
  ms-help://embarcadero.rs_xe/codesamples/Delphirtti_(C++).html
  http://qc.embarcadero.com/wc/qcmain.aspx?d=79481
  http://qc.embarcadero.com/wc/qcmain.aspx?d=104346
*/
}
Workarounds
None
Attachment
None
Comments

Moritz Beutel at 6/8/2012 9:02:12 AM -
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

__declspec(delphirtti) only affects the generation of METHODINFO-style RTTI which dates back to Delphi 6 or 7.

Luis Branca at 6/8/2012 10:29:47 AM -
Agreed! It now works as shown by Moritz. Please close the case.

Tomohiro Takahashi at 6/8/2012 8:08:56 PM -
ok, I closed this report.

Moritz Beutel at 6/8/2012 9:04:05 AM -
By the way, the "Enable RTTI" switch in the project options is historical and only affects C++ RTTI:
http://docwiki.embarcadero.com/RADStudio/en/Run-Time_Type_Identification_%28RTTI%29_Overview
http://docwiki.embarcadero.com/RADStudio/en/Rtti,_-RT_Option

Server Response from: ETNACODE01