RPC functions limited by 4 arguments.

16 Dec 2009

Just needed to add one more PinName argument to an RPC function, and compiler barked. I found out that rpc.h has only up to 4 arguments, and I'm trying to use 5. Can someone add templates with more arguments (maybe up to 10) to rpc.h?

16 Dec 2009 . Edited: 16 Dec 2009

It looks like there are 2 places that need to change - rpc.h and Base.h.

 

Here's what I did in my project:

 

1. Added this to myrpc.h (or other rpc-able class header)

 

#include "Base.h"
#include "mbed.h"
#ifdef MBED_RPC
#include "rpc.h"
#endif
 
namespace mbed {

// Fixing rpc.h limitation of 4 arguments.
#ifdef MBED_RPC
template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, R (*func)(A1,A2,A3,A4,A5)>
void rpc_function_caller(const char *arguments, char *result) {

    const char *next = arguments;
    A1 arg1 = parse_arg<A1>(next_arg(next),&next);
    A2 arg2 = parse_arg<A2>(next_arg(next),&next);
    A3 arg3 = parse_arg<A3>(next_arg(next),&next);
    A4 arg4 = parse_arg<A4>(next_arg(next),&next);
    A5 arg5 = parse_arg<A5>(next_arg(next),NULL);

    R res = (*func)(arg1,arg2,arg3,arg4,arg5);
    if(result != NULL) {
        write_result<R>(res, result);
    }
}
#endif

... 

 

 

2. Copied Base.h from SVN into project (I just used browser http://mbed.org/projects/libraries/svn/mbed/trunk/Base.h, copy-pasted and removed leading line numbers). Then added this to the end of the Base class:

 

    template
    static const char *construct(A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5) {
        Base *p = new C(arg1,arg2,arg3,arg4,arg5);
        p->_from_construct = true;
        if(p->_name==NULL) {
            p->register_object(new_name(p));
        }
        return p->_name;
    }

 

It compiles!!

 

Of course I still would want to see Base.h updated with more construct templates and rpc.h updated with more rpc_function_caller templates. After all, 4 arguments is such a small limitation, for 26 pins of available IO I think rpc should support up to 27 arguments (one for object name passing to Base).

16 Dec 2009

One thing I was not clear about - it is number of arguments in class constructor that RPC limits to 4. In other functions there is not much need for many arguments, but constructor should be able to configure a lot of different things at once. I just had a 3-pin interface converted to a 4-pin interface. It is easy to see more pins used in one interface, say in a 7-segment indicator, or keypad entry module. Not being able to make them RPC-able is a downside.

13 May 2010

Hi,

I'm trying to use RPC to send some data over the I2C bus. I need to use 5 (or possibly 6) arguments and have tried to add the modified Base.h file and the extra code to myrpc.h but it still throws up the same compilation error - No instance of overloaded function "mbed::rpc_method_caller" matches the required type (E386). As soon as I go back to 4 arguments it starts working again so I'm guessing that the number of arguments is the issue.

Have you got any other suggestions / ideas?

Thanks

13 May 2010

Hi Mike,

Take a look at:

http://mbed.org/projects/libraries/svn/mbed/trunk/rpc.h#L390

This shows you how rpc_method_caller is implemented. Assuming you understand what is going on enough (templates can be confusing I know), just use this as a outline of how to write an rpc_method_caller that supports the arguments you need.

At some point i'll revisit the way RPC is implemented as i'm convinced there is a better way, just haven't found it yet.

Hope this helps get you going; please report back.

Simon

14 May 2010

Hi Simon,

Thanks a lot for your very quick response. I've written an additional template as follows as there appears to be templates defined with arguments up to A3 but not any more:

 

template
void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
    
    const char *next = arguments;
    A1 arg1 = parse_arg(next_arg(next),&next);
    A2 arg2 = parse_arg(next_arg(next),&next);
    A3 arg3 = parse_arg(next_arg(next),&next);
    A4 arg4 = parse_arg(next_arg(next),NULL);

    R res = (static_cast(this_ptr)->*member)(arg1,arg2,arg3,arg4);
    if(result != NULL) {
        write_result(res, result);
    }
} 


and put it in the myrpc.h file within the mbed namespace declaration and everything compiles but when I add the additional arguments it fails as before with the same error message.

My C++ is a bit limited / rusty so sorry if it's something fairly simple! (But any help much appreciated)

Mike

19 May 2010

Hi Simon,

Thanks for the pointers in the right direction - managed to get it working. Just in case anyone else is interested in doing this then I've created a notebook with details here

Regards,

Mike