when trying to load a macro.C with some classes I get this message:
Limitation: Reference member not supported. Please use pointer /opt/root/pro/include/TGenericClassInfo.h:33:
*** Interpreter error recovered ***
Could you point to some resources about this issue? In which contect is exactly reference member not supported? Thanks,
Hi, I am using 5.15/08 at the moment. I do not include it myself, but I heaviliy use ROOT in my application. If you want I can find out the inclusion sequence. But if this is fixed in 5.16/00 or HEAD it is ok for me to wait a few weeks (I want to release my software with tagged versions of ROOT/AliROOT only). A related question: If there is a reference in a class, would it suffice to use a specially engineered Constructor(TROOTIOConstructor*) or to just make the reference member not persisten by //! ? or is it really not fixable? Thanks,
Since we are discussing about dictionaries, another question: I really need to have access to a private data member of a base class, specifically a pointer. Which is the most straightforward way to do this. I was looking in TDictionary for something like:
void* GetDataMemberByName(const char* name)
so I can cast it afterwards but I did not find. Any suggestions?
[quote]so I can cast it afterwards but I did not find. Any suggestions? [/quote]You can to use either TClass::GetListOfDataMembers or TClass::GetListOfRealData (which includes also the base class data member and offset). However it might be more practical to use the TStreamerElement from the TStreamerInfo (TClass::GetStreamerInfo).
OK, now I am officially lost
For the reference topic: Probably you mean NOT persistent, right? In any case, TGenericClassInfo has this problem on my ROOT version. From which version on is it fixed? I do not use myself references I believe, at least not in the context where the error occurs.
For the dictionary: I still could not find a specific way, but these 2 come in mind:
TClass:GetListOfRealData or TClass:GetListOfDataMembers and then get the data member by TList::FindObject
The problem is, the object I am looking for is a raw pointer of some struct not inheriting from TObject. In any case, what is the content of this specific TList returned?
Regarding the TStreamerInfo method, I assume I will get a TStreamerBasicPointer pointer to an object, but then how can I access the real address of the raw object (the private data member) in memory. I can only thing of using somehow the TStreamerElement::GetStreamer::operator() but I do not understand what should be the arguments.
I note that I only need to run anything just once, to get access to this private pointer, so it does not have to be anything simple
[quote]For the reference topic: Probably you mean NOT persistent, right?[/quote]Yes that’s what I meant
[quote] I do not use myself references I believe, at least not in the context where the error occurs. [/quote]Yes you are not the source of the error.
The source of the error is the improper include of TGenericClassInfo.h …
[quote]For the dictionary:[/quote]What are you trying to achieve (I am asking about the big picture). Maybe an alternative tool (like TTreeFormula) that already does the hard stuff, could be useful.
Anyway you best bet is properly something like:TClass *cl = TClass::GetClass(myclass_name);
cl->GetStreamerInflo(); // Insure that the list of real data is setup properly
TRealData *d = (TRealData*)cl->GetListOfRealData()->FindObject(data_member_name);
void *pointer_to_data = ((char*)pointer_to_object) + d-> GetThisOffset();
OK, this fails with the message:
Error in TClass::New: cannot create object of class TMySQLServer
The statement that produces this is cl->GetStreamerInfo but if I dont use it nothing works.
if(fServer) delete fServer;
fServer=new TMySQLServer(db, uid, pw);
cl->GetStreamerInfo(); // Insure that the list of real data is setup properly
std::cerr << pointer_to_data->user << std::endl;
if(fServer) delete fServer;
fServer=new TMySQLServer(db, uid, pw);
cl->BuildRealData(fServer); // Insure that the list of real data is setup properly
std::cerr << pointer_to_data << std::endl;
The last line produces:
*** Break *** segmentation violation
Using host libthread_db library “/lib/tls/libthread_db.so.1”.
Attaching to program: /proc/29623/exe, process 29623
[Thread debugging using libthread_db enabled]
[New Thread -1208436512 (LWP 29623)]
0x003177a2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2 #1 0x0705d473 in __waitpid_nocancel () from /lib/tls/libc.so.6 #2 0x07007359 in do_system () from /lib/tls/libc.so.6 #3 0x0030878d in system () from /lib/tls/libpthread.so.0 #4 0x03096747 in TUnixSystem::Exec () from /opt/root/pro/lib/libCore.so #5 0x0309bed9 in TUnixSystem::StackTrace () from /opt/root/pro/lib/libCore.so #6 0x03098b39 in TUnixSystem::DispatchSignals ()
from /opt/root/pro/lib/libCore.so #7 0x03098c40 in SigHandler () from /opt/root/pro/lib/libCore.so #8 0x03097e19 in sighandler () from /opt/root/pro/lib/libCore.so #9 #10 0x0090a207 in amore::core::PoolInterface::Connect (this=0xbff932a4,
db=0x8c7d644 “mysql://host/AMORE”, uid=0x8c7c684 “uid”,
pw=0x8c7c69c “pw”) at /opt/root/pro/include/TRealData.h:55
It seems from the last line that something happens wrong with TRealData::GetThisOffset so the final raw pointer is not the correct address. Any ideas? What I want to do is to override the “Prepared statements” mechanism of TMySqlServer for my work. The only change needed would be to make the private data members of TMySQLServer and TMySQLStatement protected I think.
[quote]What I want to do is to override the “Prepared statements” mechanism of TMySqlServer for my work. The only change needed would be to make the private data members of TMySQLServer and TMySQLStatement protected I think.[/quote]Yes this is the right think to do (this modification has been uploaded to the CVS repository).
Actually what happens is that there is no TRealData object for ‘fMySQL’, hence d is null, hence the crash. There is no TRealData object for ‘fMySQL’, because this data member is not persistent (and hence we do not attempt in any way to calculate its offset).
You are right, I just checked on the root prompt that the TRealData pointer is zero. I don’t know how I missed checking that I was under the impression that one needed to put //! to avoid persistence. Anyway, thanks for the modification on TMySQLServer. I think also TMySQLStatement needs to have protected data members instead of private. The plan for me was to have amore::core::MySQLServer: public TMySqlServer returning amore::core::MySqlStatement: public TMySQLStatement. I would appreciate it if this final modification would be possible. Thanks,
Thanks for the modification. I am interested in changing the BLOB (Binary) data handling mechanism. At the moment if follows copy semantics, data are copied internally everytime the statement is executed. I just want TMySQLStatement to transfer whatever is available in a container of pointers at the time of the statement execution, as I think is the case with the native MySQL C API (admitetely I am new to MySQL so this may fail/be incorrect). I have thought of a solution some months ago but at the moment I think the most elegant one is to really create a TMySQLStatementBind class that does the actual binding and provides a reference semantics interface (e.g. SetInt(int* val)) and feed an object of this class as input to TMySQLStatement. In any case I aim for genericity and lightweight implementation but I may finally end up with something that is very specific to my application. cheers,
Generally, you are right. MySQL plugin in ROOT (as well as Oracle and ODBC) uses internal memory buffers to get data from database first and than copy it to user buffer when requested.
I see no problem to implement something like you proposing with TMySQLStatementBind class, but it should be general enough to be implemented in the same manner for Oracle, ODBC and Postgres (where statement class are supported).
I also think, that avoiding additional memcpy does not increase performance too much - your performance mostly limited by network and database itself.