Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 23, 2009 Pointer to method C++ style | ||||
---|---|---|---|---|
| ||||
Is there a way to declare and statically initialize some sort of pointer to method, and later call it for an actual object instance? Use case: I'm writing an ActiveX plug-in for a dynamic language. The language queries the component for implemented methods, then it requests these methods to be executed. I want to implement these methods as the component class non-static members, and create a lookup table at compile time, sort of struct Method { string name; PointerToMember method; // some magic goes here } class Component : IUnknown { void method1() {} void method2() {} static Method[] LOOKUP_TABLE = [ { "method1", &method1 }, // won't work, &method1 is non-const { "method2", &method2 } ]; void call(int i) { this->*LOOKUP_TABLE[i].method(); // sort of } } |
July 23, 2009 Re: Pointer to method C++ style | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sergey Gromov | Hello Sergey,
> Is there a way to declare and statically initialize some sort of
> pointer to method, and later call it for an actual object instance?
>
dosn't work but might point you in the right direction:
template Pn2Fn(R, char[] method)
{
ReturnTypeOf!(mixin("R." ~ method)) Pn2Fn(R r, ArgsOf!(mixin("R." ~ method)) args)
{
return mixin("r."~method~"(args);");
}
}
// use
auto it = &Pn2Fn!(Type, "method");
//call as
it(type);
|
July 23, 2009 Re: Pointer to method C++ style | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sergey Gromov | Sergey Gromov wrote: > Use case: I'm writing an ActiveX plug-in for a dynamic language. The > class Component : IUnknown WOW! But shouldn't you use class Component : IDispatch { HRESULT QueryInterface( REFIID riid, LPVOID * ppvObj) {}; ULONG AddRef() {}; ULONG Release(){}; // plus IDispatch methods // GetTypeInfoCount, GetTypeInfo, GetIDsOfNames, Invoke. // to support late binding ? } instead ? Beside, John C. (Juno library) is a specialist (guru) regarding this topic. maybe he is willing to help. However, I am _very_ interested in having/seeing the source of a very basic ActiveX control. Any chance that you share the core implementation with us ? björn |
July 23, 2009 Re: Pointer to method C++ style | ||||
---|---|---|---|---|
| ||||
Posted in reply to BLS | Thu, 23 Jul 2009 12:37:42 +0200, BLS wrote:
>Sergey Gromov wrote:
>> Use case: I'm writing an ActiveX plug-in for a dynamic language. The
>
> However, I am _very_ interested in having/seeing the source of a very basic ActiveX control. Any chance that you share the core implementation with us ?
Sorry, I'm not a guru at all, so ActiveX was a misnomer. What I'm writing is a simple in-process server DLL which implements a couple of interfaces.
|
July 23, 2009 Re: Pointer to method C++ style | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | Thu, 23 Jul 2009 04:11:14 +0000 (UTC), BCS wrote:
> Hello Sergey,
>
>> Is there a way to declare and statically initialize some sort of pointer to method, and later call it for an actual object instance?
>>
>
> dosn't work but might point you in the right direction:
>
> template Pn2Fn(R, char[] method)
> {
> ReturnTypeOf!(mixin("R." ~ method)) Pn2Fn(R r, ArgsOf!(mixin("R." ~
> method)) args)
> {
> return mixin("r."~method~"(args);");
> }
>
> }
Thanks for the advice. The following code actually works:
import std.stdio;
struct Handler(T)
{
string name;
void function(T instance) handler;
}
class A
{
void method1() { writefln("method1"); }
void method2() { writefln("method2"); }
void call(int i)
{
LOOKUP_TABLE[i].handler(this);
}
private:
static Handler!(A)[] LOOKUP_TABLE =
[
{ "method1", &callMethod!("method1") },
{ "method2", &callMethod!("method2") }
];
static void callMethod(string name)(A instance)
{
mixin("instance." ~ name ~ "();");
}
}
void main()
{
A a = new A;
a.call(0);
a.call(1);
}
|
July 23, 2009 Re: Pointer to method C++ style | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sergey Gromov | On Wed, 22 Jul 2009 23:47:30 -0400, Sergey Gromov <snake.scaly@gmail.com> wrote:
> Is there a way to declare and statically initialize some sort of pointer
> to method, and later call it for an actual object instance?
I don't know why the "non constant expression error" happens, but constructing a delegate from function pointers is pretty simple:
import tango.io.Stdout;
struct Method
{
char[] name;
void function() method;
}
class Component
{
void method1() {Stdout("method1").newline;}
void method2() {Stdout("method2").newline;}
// this works, but not sure why I couldn't initialize via a simple array assign...
static Method[] LOOKUP_TABLE;
static this()
{
LOOKUP_TABLE = new Method[2];
LOOKUP_TABLE[0] = Method("method1", &Component.method1);
LOOKUP_TABLE[1] = Method("method2", &Component.method2);
}
void call(int i)
{
// construct a delegate to call
void delegate() dg;
dg.ptr = cast(void*)this;
dg.funcptr = LOOKUP_TABLE[i].method;
// call the delegate
dg();
}
}
void main()
{
Component a = new Component;
a.call(0);
a.call(1);
}
-------
outputs:
method1
method2
-Steve
|
July 23, 2009 Re: Pointer to method C++ style | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sergey Gromov | Sergey Gromov wrote: > Thu, 23 Jul 2009 12:37:42 +0200, BLS wrote: > > Sorry, I'm not a guru at all, so ActiveX was a misnomer. What I'm > writing is a simple in-process server DLL which implements a couple of > interfaces. Oh, that's sad. :( well, especially in this case I would suggest to have a look on this page : http://www.dsource.org/projects/juno/wiki/ComProgramming --- I think John's juno.com.server module contains almost everything you need. good luck |
July 23, 2009 Re: Pointer to method C++ style | ||||
---|---|---|---|---|
| ||||
Posted in reply to BLS | Thu, 23 Jul 2009 19:07:43 +0200, BLS wrote:
> Sergey Gromov wrote:
>> Sorry, I'm not a guru at all, so ActiveX was a misnomer. What I'm writing is a simple in-process server DLL which implements a couple of interfaces.
>
> Oh, that's sad. :(
>
> well, especially in this case I would suggest to have a look on this page : http://www.dsource.org/projects/juno/wiki/ComProgramming
Thanks, I'll look into it when I have time.
|
July 24, 2009 Re: Pointer to method C++ style | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Thu, 23 Jul 2009 11:54:40 -0400, Steven Schveighoffer wrote: > On Wed, 22 Jul 2009 23:47:30 -0400, Sergey Gromov <snake.scaly@gmail.com> wrote: > >> Is there a way to declare and statically initialize some sort of pointer to method, and later call it for an actual object instance? > > I don't know why the "non constant expression error" happens, but constructing a delegate from function pointers is pretty simple: It's my understanding that you cannot construct a delegate from a function pointer because they use different calling conventions. Though you show here that it *is* possible to construct a delegate from another delegate you dissected earlier. > LOOKUP_TABLE[0] = Method("method1", &Component.method1); > LOOKUP_TABLE[1] = Method("method2", &Component.method2); These two lines are weird. ``pragma(msg)`` shows that type of ``&method1`` is ``void function()`` while it must be ``void delegate()`` for a non-static member because of difference in calling convention. Actually I think that taking an address of a non-static member in a static context must be a compile time error. |
July 24, 2009 Re: Pointer to method C++ style | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sergey Gromov | On Thu, 23 Jul 2009 22:09:12 -0400, Sergey Gromov <snake.scaly@gmail.com> wrote:
> Thu, 23 Jul 2009 11:54:40 -0400, Steven Schveighoffer wrote:
>
>> On Wed, 22 Jul 2009 23:47:30 -0400, Sergey Gromov <snake.scaly@gmail.com>
>> wrote:
>>
>>> Is there a way to declare and statically initialize some sort of pointer
>>> to method, and later call it for an actual object instance?
>>
>> I don't know why the "non constant expression error" happens, but
>> constructing a delegate from function pointers is pretty simple:
>
> It's my understanding that you cannot construct a delegate from a
> function pointer because they use different calling conventions. Though
> you show here that it *is* possible to construct a delegate from another
> delegate you dissected earlier.
>
>> LOOKUP_TABLE[0] = Method("method1", &Component.method1);
>> LOOKUP_TABLE[1] = Method("method2", &Component.method2);
>
> These two lines are weird. ``pragma(msg)`` shows that type of
> ``&method1`` is ``void function()`` while it must be ``void delegate()``
> for a non-static member because of difference in calling convention.
> Actually I think that taking an address of a non-static member in a
> static context must be a compile time error.
It's because I'm taking the address of the function on the type, not on an instance. It's not a delegate because there's no "this" pointer yet.
It makes sense to me anyways. A delegate is a normal function pointer coupled with a hidden context parameter.
I think it should be possible to construct the table statically, since the functions exist statically (without 'this' pointers). Either I can't find the right syntax, or it is a bug.
-Steve
|
Copyright © 1999-2021 by the D Language Foundation