Re: Pointer to method C++ style

2009-07-24 Thread Sergey Gromov
Fri, 24 Jul 2009 02:51:45 +0400, Sergey Gromov wrote:

> 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.

Juno is nice, and implements a lot of boilerplate.  But it doesn't seem
to care enough about exceptions in user code.  My own code wraps every
interface function in an exception catching block, and I'd better leave
it that way.


Re: Pointer to method C++ style

2009-07-24 Thread Sergey Gromov
Fri, 24 Jul 2009 09:07:30 -0400, Steven Schveighoffer wrote:

> On Thu, 23 Jul 2009 22:09:12 -0400, Sergey Gromov   
> wrote:
> 
>> Thu, 23 Jul 2009 11:54:40 -0400, Steven Schveighoffer wrote:
>>
>>>  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.

The ``Type.`` part does not change anything.  It simply directs compiler
to use overloads from a particular class hierarchy level.   Here:

static Method[] LOOKUP_TABLE2 = [
{ name : "method1", method : &Component.method1 },
{ name : "method2", method : &method2 }
];

This code compiled with DMD 1.046 gives the following errors:

test2.d(30): Error: non-constant expression & method1
test2.d(30): Error: non-constant expression & method2

Also if you add this code:

pragma(msg, "outside: " ~ typeof(&method1).stringof);
void method1() { writefln("method1");
pragma(msg, "inmeth: " ~ typeof(&method1).stringof);
}

you get:

outside: void function()
inmeth: void delegate()

So the type of a non-static method address taken in a static context is
obviously wrong.


Re: Pointer to method C++ style

2009-07-24 Thread Steven Schveighoffer

On Fri, 24 Jul 2009 09:56:41 -0400, grauzone  wrote:


 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.


But you can't call that function pointer. Actually, you can probably  
subvert type safety, because functions have a different calling  
conventions from delegates. This also means that SafeD should disallow  
taking the address of methods from a type (without instance).


That's really silly. A nicer way would be to make &Type.method return a  
delegate with ptr set to null. Then calling this delegate would result  
in a (harmless) null pointer exception.


But even then, there's no safe way to construct a real delegate out of  
the method pointer. You can't simply assign an object instance to ptr,  
because you can't statically know if the funcptr of the delegate really  
is a method of that object instance.


You mean no *compiler verifyable* safe way.  Of course there are provably  
safe ways to do it (my code is one of them).



Looks like SafeD proves to be unfeasible again.


That's why there are system modules ;)  Note that a delegate's ptr method  
is a pointer, so you can't assign it/use it from SafeD anyways.


I'd propose a system module that defines an "unbound delegate" type.  This  
would be a function pointer coupled parameterized with a type, which has  
an opCall(T, ...) that would call the function properly.  I think it can  
be done, but I'm not enough of a template guru to do it myself.


That could be used in SafeD.

-Steve


Re: Pointer to method C++ style

2009-07-24 Thread grauzone

 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.


But you can't call that function pointer. Actually, you can probably 
subvert type safety, because functions have a different calling 
conventions from delegates. This also means that SafeD should disallow 
taking the address of methods from a type (without instance).


That's really silly. A nicer way would be to make &Type.method return a 
delegate with ptr set to null. Then calling this delegate would result 
in a (harmless) null pointer exception.


But even then, there's no safe way to construct a real delegate out of 
the method pointer. You can't simply assign an object instance to ptr, 
because you can't statically know if the funcptr of the delegate really 
is a method of that object instance.


Looks like SafeD proves to be unfeasible again.


Re: Pointer to method C++ style

2009-07-24 Thread Steven Schveighoffer
On Thu, 23 Jul 2009 22:09:12 -0400, Sergey Gromov   
wrote:



Thu, 23 Jul 2009 11:54:40 -0400, Steven Schveighoffer wrote:

On Wed, 22 Jul 2009 23:47:30 -0400, Sergey Gromov  


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


Re: Pointer to method C++ style

2009-07-23 Thread Sergey Gromov
Thu, 23 Jul 2009 11:54:40 -0400, Steven Schveighoffer wrote:

> On Wed, 22 Jul 2009 23:47:30 -0400, Sergey Gromov   
> 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.


Re: Pointer to method C++ style

2009-07-23 Thread Sergey Gromov
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.


Re: Pointer to method C++ style

2009-07-23 Thread BLS

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













Re: Pointer to method C++ style

2009-07-23 Thread Steven Schveighoffer
On Wed, 22 Jul 2009 23:47:30 -0400, Sergey Gromov   
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


Re: Pointer to method C++ style

2009-07-23 Thread Sergey Gromov
Thu, 23 Jul 2009 04:11:14 + (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);
}


Re: Pointer to method C++ style

2009-07-23 Thread Sergey Gromov
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.


Re: Pointer to method C++ style

2009-07-23 Thread BLS

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




Re: Pointer to method C++ style

2009-07-22 Thread BCS

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);




Pointer to method C++ style

2009-07-22 Thread Sergey Gromov
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
}
}