[Solved]Reflex: How to get return value of Member::Invoke()?

Hello,

I am a newbie C++ developer (lots of Java experience). I am trying to create a very simple servlet container based on Poco, and need to use some dynamic instance creation to perform servlet to path mapping based on a configuration file.

I found the Reflex framework and was trying out a simple sample program based on the example code given at seal-reflex.web.cern.ch/seal-ref … mples.html. I got the basics working, but ran into a roadblock when trying to add some extra code. I looked at the unit test suite, and the tests invoking retrieving the returned value from the Invoke method have been commented out (as has the API changed from what the online documentation shows).

I added the following code to my simple test:

Member fm = t.FunctionMemberByName("getVal"); Object result( Type::ByName( "int" ) ); fm.Invoke(o, &result);

The question is, how do I get the result value that is stored in result? In my case I should be getting an integer, but I cannot seem to find the proper way to get at the value from the documentation.

Thanks in advance for all help and suggestions.
Rakesh

Okay, I found the Address method, but it still does not work properly

[code] Member dm = t.DataMemberByName(“val”);
cout << "Data member " << dm.Name() << " is of type " << dm.TypeOf().Name() << endl;
int i = Object_Cast(dm.Get(o));
cout << "Data member " << dm.Name() << " value is " << i << endl;
++i;
dm.Set(o,&i);
cout << "Data member " << dm.Name() << " set to " << Object_Cast(dm.Get(o)) << endl;

Member fm = t.FunctionMemberByName("getVal");
cout << "Function " << fm.Name() << " is of type " << fm.TypeOf().Name() << endl;
Object result( Type::ByName( "int" ) );
fm.Invoke(o, &result);
int *val = static_cast<int *>( result.Address() );
cout << "Function getVal returned " << val << endl;[/code]

The last line prints the value is 0 (null pointer?), while I had set the value to 1 through the previous dm.Set call. If I try to dereference the val pointer, I get a memory fault. Any ideas as to what I am doing wrong?

Hi,

Did you try:Object_Cast<int>(result);?

Cheers,
Philippe.

PS. Which version of Reflex/ROOT did you try this on?

Hi Philippe,

That results in a memory fault crash (null pointer). I am using reflex from root.cern.ch/svn/root/branches/dev/cint/reflex

Thanks
Rakesh

Hi Rakesh,

Can you try with the official trunk: root.cern.ch/svn/root/trunk/cint/reflex ?

Cheers,
Philippe.

Hi Philippe,

Unfortunately, I get the same result. Here is an excerpt from the crash log:

[code]Process: test [71530]
Path: /Users/rakesh/projects/cpp/test/reflex/test
Identifier: test
Version: ??? (???)
Code Type: X86-64 (Native)
Parent Process: ksh [68774]

Date/Time: 2012-02-08 14:11:19.818 -0600
OS Version: Mac OS X 10.6.8 (10K549)
Report Version: 6

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000
Crashed Thread: 0 Dispatch queue: com.apple.main-thread

Thread 0 Crashed: Dispatch queue: com.apple.main-thread
0 test 0x00000001000033ac int Reflex::Object_Cast(Reflex::Object const&) + 21
1 test 0x0000000100002f3d main + 2738
2 test 0x000000010000236c start + 52[/code]

Hi,

You are using the Objct contructor:

   Object(const Type& type = Type(),
          void* mem = 0);

Now guess what memory address the object points to :wink: Instead, please use e.g.

int iRes = -1;
Object result = Object::Create(iRes);

or allocate it with Type::Allocate().

Cheers, Axel.

Ah…, thanks. I had not looked at the constructor declaration.

Rakesh