[ROOT] STL strings at the CINT / Compiled code boundary

From: Robert Hatcher (rhatcher@SLAC.stanford.edu)
Date: Thu Aug 02 2001 - 03:36:36 MEST


My system:  ROOT 3.01/06+ (CVS as of Jul 27), Linux RH6.2
  (attempted with different machines having egcs and gcc2.95)

I have some compiled classes that use STL strings as args and return
values.  I'd like to interact with these from within a CINT macro.
But neither of these seems to work.  In passing a CINT string
to a compiled routine it complains about a signature mismatch.
In the reverse it tends to fill the CINT string with garbage
that generally leads to unhappiness (SEGV or random characters
that change the terminal's character set).

This can be demonstrated with a stripped down macro and a class.

 root[] .L StringUser.C++
 root[] .x testSU.C

========= testSU.C =======================================
#include <string>
void testSU()
{
   // a macro to test the interaction of CINT with compiled code

   // StringUser::SelfTest();  // works as expected

   string abc("abc");
   StringUser su;

   bool test1 = true;
   bool test2 = false;

   if (test1) {
      cout << "pass string to object" << endl;
      su.TakeStringObj(abc);
// gives:
//-------------
// Error: Can't call StringUser::TakeStringObj(abc) in current scope FILE:testSU.C LINE:8
// Possible candidates are...
// filename       line:size busy function type and name  (in StringUser)
// (compiled)        0:0    0 public: void TakeStringObj(string s);
// *** Interpreter error recovered ***

   }

   if (test2) {
      cout << "retrieve string from object into existing string" << endl;
      abc = su.ReturnStringObj();
      cout << " returned " << abc << endl;
// gives:
//-------------
// insidious failure tends to generate
//  *** Break *** segmentation violation
// or garbage characters during the cout of "abc"
   }

   cout << "all done" << endl;
}

========= StringUser.C =======================================
#include <iostream>
#include <string>
// for ClassDef
#include "Rtypes.h"

class StringUser {
  public:
   void   TakeStringObj(string s);
   string ReturnStringObj();

   static void   TakeStringStatic(string s);
   static string ReturnStringStatic();

   static void    SelfTest(const char* cstr = "xyzzy");
   static string  fgStringValue;

   ClassDef(StringUser,0)
};

ClassImp(StringUser)

// static space
string StringUser::fgStringValue = "default";

// function definitions
void StringUser::TakeStringObj(string s)
{
   StringUser::TakeStringStatic(s);
}

string StringUser::ReturnStringObj()
{
   return StringUser::ReturnStringStatic();
}

void StringUser::TakeStringStatic(string s)
{
   fgStringValue = s;
}

string StringUser::ReturnStringStatic()
{
   return fgStringValue;
}

void StringUser::SelfTest(const char* cstr)
{
   cout << "StringUser::SelfTest was passed \"" << cstr << "\"" << endl;
   string tmp = cstr;

   // test implicit conversion
   StringUser::TakeStringStatic(cstr);
   string goti = StringUser::ReturnStringStatic();
   cout << " implicit returned \""
        << goti << "\" was "
        << ((goti == tmp) ? "ok" : "mismatched")
        << endl;

   // test with explicit conversion
   StringUser::TakeStringStatic(tmp);
   string gote = StringUser::ReturnStringStatic();
   cout << " explicit returned \""
        << gote << "\" was "
        << ((gote == tmp) ? "ok" : "mismatched")
        << endl;

   string setto = tmp + "obj";
   StringUser su;
   su.TakeStringObj(setto);
   string gotobj = su.ReturnStringObj();
   cout << " test with obj returned \""
        << gotobj << "\" was "
        << ((gotobj == setto) ? "ok" : "mismatched")
        << endl;

}


Robert W. Hatcher   |  rhatcher@slac.stanford.edu
Research Associate  |  650.926.3171  [FAX 4001 or 3587]
Stanford University |  PO Box 4349, MS #63, Stanford CA 94309



This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:54 MET