Macros, vTable?

Discussion in 'C++' started by Alexander Adam, Mar 12, 2007.

  1. Hi!

    I've got an issue. I have more or less an internal class model for
    which I want to write various bindings e.g. for Windows COM. Now I've
    figured to make my internal classes based on IDispatchEx which works
    fine. The biggest pain I have right now is that I need to register
    properties and methods dynamically and I need to call those
    dynamically, too. Take the following example:

    struct method {
    short calltype; // 0=property_get, 1=property_set, 2=method
    unsigned id;
    const char* name;
    int* params;
    }

    class A :
    public MyTemplate<A>
    {
    public:
    BEGIN_METHODS(A)
    METHOD(0, "something", 1, {})
    METHOD(1, "something", 2, {})
    METHOD(2, "doSomething", 3, {4,5,2})
    END_METHODS
    public:
    // Properties
    virtual std::string get_Something();
    virtual void set_Something(const std::string& name);

    // Methods
    virtual void doSomething();
    }


    Now in myTemplate I have two functions called from outside, one to get
    an unique id for the given name and type and one for calling it. The
    question I have is this:

    The biggest pain is that I've wanted to call the functions that I have
    registered with METHOD() macro directly, passing the parameters
    dynamically as an array. But as I'd require my own call stack frame
    and my asm knowledge is not the best, I've thought to create two
    functions within my BEGIN_METHODS and END_METHODS macros that is, one
    for registering the functions which could look like

    static const method* _get_methods()
    {
    ...
    }

    and one that calls it like

    void _call_method(int id, params* p)
    {
    switch( id)
    {
    case 2: doSomething(p[0].int, p[1].double);
    ....
    }


    Now as you can see the issue I have is that I cannot have my Macros
    declare two independant functions that is, to be able to create a
    _get_methods and a _call_method routine, I'd need to redeclare
    evertything like this:


    class A :
    public MyTemplate<A>
    {
    public:
    BEGIN_METHODS(A) // _get_methods()
    METHOD(0, "something", 1, {})
    METHOD(1, "something", 2, {})
    METHOD(2, "doSomething", 3, {4,5,2})
    END_METHODS


    BEGIN_METHODS2(A) // _call_method
    METHOD(0, (p[0].int, p[1].double))
    END_METHODS2
    public:
    // Properties
    virtual std::string get_Something();
    virtual void set_Something(const std::string& name);

    // Methods
    virtual void doSomething();
    }


    You might see my issue here -- I have to declare everything twice
    which is not really nice.

    So after fighting and trying and everything for days, I was hoping
    that someone could help me out here with a smart advice, hint, help or
    anything?

    Thanks and Regards
    Alexander
     
    Alexander Adam, Mar 12, 2007
    #1
    1. Advertising

  2. Alexander Adam wrote:
    > Hi!
    >
    > I've got an issue. I have more or less an internal class model for
    > which I want to write various bindings e.g. for Windows COM. Now I've
    > figured to make my internal classes based on IDispatchEx which works
    > fine. The biggest pain I have right now is that I need to register
    > properties and methods dynamically and I need to call those
    > dynamically, too. Take the following example:
    >
    > struct method {
    > short calltype; // 0=property_get, 1=property_set, 2=method
    > unsigned id;
    > const char* name;
    > int* params;
    > }
    >
    > class A :
    > public MyTemplate<A>
    > {
    > public:
    > BEGIN_METHODS(A)
    > METHOD(0, "something", 1, {})
    > METHOD(1, "something", 2, {})
    > METHOD(2, "doSomething", 3, {4,5,2})
    > END_METHODS
    > public:
    > // Properties
    > virtual std::string get_Something();
    > virtual void set_Something(const std::string& name);
    >
    > // Methods
    > virtual void doSomething();
    > }
    >
    >
    > Now in myTemplate I have two functions called from outside, one to get
    > an unique id for the given name and type and one for calling it. The
    > question I have is this:
    >
    > The biggest pain is that I've wanted to call the functions that I have
    > registered with METHOD() macro directly, passing the parameters
    > dynamically as an array. But as I'd require my own call stack frame
    > and my asm knowledge is not the best, I've thought to create two
    > functions within my BEGIN_METHODS and END_METHODS macros that is, one
    > for registering the functions which could look like
    >
    > static const method* _get_methods()
    > {
    > ...
    > }
    >
    > and one that calls it like
    >
    > void _call_method(int id, params* p)
    > {
    > switch( id)
    > {
    > case 2: doSomething(p[0].int, p[1].double);
    > ...
    > }
    >
    >
    > Now as you can see the issue I have is that I cannot have my Macros
    > declare two independant functions that is, to be able to create a
    > _get_methods and a _call_method routine, I'd need to redeclare
    > evertything like this:
    >
    >
    > class A :
    > public MyTemplate<A>
    > {
    > public:
    > BEGIN_METHODS(A) // _get_methods()
    > METHOD(0, "something", 1, {})
    > METHOD(1, "something", 2, {})
    > METHOD(2, "doSomething", 3, {4,5,2})
    > END_METHODS
    >
    >
    > BEGIN_METHODS2(A) // _call_method
    > METHOD(0, (p[0].int, p[1].double))
    > END_METHODS2
    > public:
    > // Properties
    > virtual std::string get_Something();
    > virtual void set_Something(const std::string& name);
    >
    > // Methods
    > virtual void doSomething();
    > }
    >
    >
    > You might see my issue here -- I have to declare everything twice
    > which is not really nice.
    >
    > So after fighting and trying and everything for days, I was hoping
    > that someone could help me out here with a smart advice, hint, help or
    > anything?


    Well, my honest advice would be give up and do something more productive
    with your time. But I guess you don't want me to tell you that.

    So.

    Why not combine _get_methods and _call_method into a single function?
    Any reason that can't be done? Sure it's ugly but you seem to be in ugly
    territory anyway.

    john
     
    John Harrison, Mar 12, 2007
    #2
    1. Advertising

  3. Hi,

    > Well, my honest advice would be give up and do something more productive
    > with your time. But I guess you don't want me to tell you that.


    How is it you come to that opinion?
    The issue here is just that the internal object model is quite huge (>
    1800 classes) and I've started building COM Wrappers around each
    object but it took way too much time to just implement a few classes
    so I've decided to let each single class be the COM Object itself.

    > So.
    >
    > Why not combine _get_methods and _call_method into a single function?
    > Any reason that can't be done? Sure it's ugly but you seem to be in ugly
    > territory anyway.


    Uhm that's what I've tried first, too. The issue is just that I need
    to register the function before using it within _call_method. This is
    necessary to be able to check for parameters count, types etc. and
    combining both into one function wouldn't really work in this case as
    the code gets really really unusable. How's it you're saying that I
    seem to be in ugly territory anyway, do you mean my C Code is ugly?
    Well I've just written that as more or less pseudo code, not saying
    that the original code looks as crappy as this one. Or is it that you
    say calling dynamic functions is the ugly territory?

    I'd be very thankful for some more hints on such kind of issue, I
    can't believe I am the only one having this as calling dynamic
    functions including dynamic parameters and returns seems to me as a
    quite common problem?

    Regards
    Alexander
     
    Alexander Adam, Mar 12, 2007
    #3
  4. Alexander Adam wrote:

    > Hi!
    >
    > I've got an issue. I have more or less an internal class model for
    > which I want to write various bindings e.g. for Windows COM.


    If I understand you right, you have some classes written (presumably) in
    C++, but you want to publish your framework via Microsoft COM to the
    world. This involves a lot of work, as you can only define interfaces in
    COM, whereas C++ mixes interfaces and implementation into single
    entities. This means that you'll have to untangle interfaces from
    implementations by hand, which is going to be quite time-consuming.

    > Now I've
    > figured to make my internal classes based on IDispatchEx which works
    > fine. The biggest pain I have right now is that I need to register
    > properties and methods dynamically and I need to call those
    > dynamically, too. Take the following example:


    I don't believe that working with IDispatchEx is useful here, as you'll
    need to work over your code completely. So instead of doing this, you
    may as well start with defining real COM interfaces and make your C++
    classes to implementors of these interfaces.

    IDispatchEx as COM interface doesn't make sense to me, as it is intended
    for dynamically adding properties and methods to objects. Adding
    properties can be done by any container class, and adding methods is not
    useful (as they cannot access private data members, and that is what
    half of object-orientation is all about: encapsulation).

    Anyway, if you're using IDispatchEx you'll have to be automation
    compatible, and I very much doubt that your C++ framework is automation
    compatible. I'd advice you to start introducing real COM (not using
    IDispatchEx) interfaces in your project step by step.

    Regards,
    Stuart
     
    Stuart Redmann, Mar 12, 2007
    #4
  5. Alexander Adam

    W Karas Guest

    On Mar 12, 2:10 am, "Alexander Adam" <> wrote:
    ....
    > Now as you can see the issue I have is that I cannot have my Macros
    > declare two independant functions that is, to be able to create a
    > _get_methods and a _call_method routine, I'd need to redeclare
    > evertything like this:
    >
    > class A :
    > public MyTemplate<A>
    > {
    > public:
    > BEGIN_METHODS(A) // _get_methods()
    > METHOD(0, "something", 1, {})
    > METHOD(1, "something", 2, {})
    > METHOD(2, "doSomething", 3, {4,5,2})
    > END_METHODS
    >
    > BEGIN_METHODS2(A) // _call_method
    > METHOD(0, (p[0].int, p[1].double))
    > END_METHODS2
    > public:
    > // Properties
    > virtual std::string get_Something();
    > virtual void set_Something(const std::string& name);
    >
    > // Methods
    > virtual void doSomething();
    >
    > }
    >
    > You might see my issue here -- I have to declare everything twice
    > which is not really nice.

    ....

    class A :
    public MyTemplate<A>
    {
    public:
    #undef L
    #define L(METHOD) \
    METHOD(0, "something", 1, {}) \
    METHOD(1, "something", 2, {}) \
    METHOD(2, "doSomething", 3, {4,5,2})

    GENERATE_GET(L)

    GENERATE_CALL(L)
    ....

    On the other hand, I'm not sure I see why you
    can't go with a (macro-free) solution that just
    uses an array:

    int doSomethingParam[] = {4,5,2};

    method myMethods[] =
    {
    {"something", 1, 0},
    {"something", 2, 0},
    {"doSomething", 3, doSomethingParam}
    };
     
    W Karas, Mar 12, 2007
    #5
  6. hi,

    >
    > class A :
    > public MyTemplate<A>
    > {
    > public:
    > #undef L
    > #define L(METHOD) \
    > METHOD(0, "something", 1, {}) \
    > METHOD(1, "something", 2, {}) \
    > METHOD(2, "doSomething", 3, {4,5,2})
    >
    > GENERATE_GET(L)
    >
    > GENERATE_CALL(L)
    > ...
    >
    > On the other hand, I'm not sure I see why you
    > can't go with a (macro-free) solution that just
    > uses an array:
    >
    > int doSomethingParam[] = {4,5,2};
    >
    > method myMethods[] =
    > {
    > {"something", 1, 0},
    > {"something", 2, 0},
    > {"doSomething", 3, doSomethingParam}
    >
    > };


    I would love to go with a macro free solution but the issue is exactly
    what you mention here -- how tp pass the doSomethingParam over to the
    dynamic function call? Because it is not one array of int but it can
    be an array of different types and should go directly into the
    function which could look like doSomething(int aNumber, string
    aValue, ..)

    Regards
    Alexander
     
    Alexander Adam, Mar 13, 2007
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    80
    Views:
    2,458
    Stephen J. Bevan
    Nov 7, 2003
  2. Replies:
    1
    Views:
    465
    Marco Antoniotti
    Oct 7, 2003
  3. Replies:
    5
    Views:
    507
  4. Michael T. Babcock

    Re: Explanation of macros; Haskell macros

    Michael T. Babcock, Nov 3, 2003, in forum: Python
    Replies:
    0
    Views:
    531
    Michael T. Babcock
    Nov 3, 2003
  5. Andrew Arro

    macros-loop? calling macros X times?

    Andrew Arro, Jul 23, 2004, in forum: C Programming
    Replies:
    2
    Views:
    510
    S.Tobias
    Jul 24, 2004
Loading...

Share This Page