June 10, 2013
On 11 June 2013 02:43, Jacob Carlborg <doob@me.com> wrote:

> On 2013-06-10 18:34, Manu wrote:
>
>> On 11 June 2013 02:26, Jacob Carlborg <doob@me.com <mailto:doob@me.com>>
>>
>> wrote:
>>
>>     On 2013-06-10 17:40, David Nadlinger wrote:
>>
>>         Let me try to summarize it in code:
>>
>>         ---
>>         class A { void foo(); }
>>         auto memberFun = (&A.foo).funcptr;
>>
>>         auto a = new A;
>>         memberFun(a);
>>         ---
>>
>>
>>     Why is this better than a delegate?
>>
>>
>> It's not 'better', it's different.
>>
>
> class A { void foo(); }
> auto memberFun = (&A.foo).funcptr;
>
> auto a = new A;
> void delegate () dg;
> dg.funcptr = memberFun;
> dg.ptr = cast(void*) a;
> dg();
>
> The details can be hidden in a function call. Sure, a delegate could be type safe but still don't see the point.


You can see how much work that is right? And it's still not typesafe. It's totally a hack.


June 10, 2013
On Mon, 10 Jun 2013 12:45:12 -0400, Jacob Carlborg <doob@me.com> wrote:

> On 2013-06-10 18:38, dennis luehring wrote:
>
>> maybe he just don't need one to handle the this ptr because he wants to
>> call several/hundrets of member-functions?
>
> How does he call a pointer to a member function without the "this" pointer?

Like this:

void callRandomMember(C[] objs, memberPointerToCMethod p)
{
   objs[random(0, objs.length)].p();
}

Essentially, you bind at call time to form a delegate.  But the member function pointer's 'this' must be strongly typed.

-Steve
June 10, 2013
On Mon, 10 Jun 2013 14:53:33 +0200, Jacob Carlborg <doob@me.com> wrote:

> On 2013-06-10 14:36, Manu wrote:
>
>> funcptr pretends to be typed, but the type is just wrong. In your
>> example, the type is 'void function()', it should be 'void function(Foo
>> this)'.
>
> "void function()" is part of the complete type. It becomes complete with the context pointer.

This is utter horseshit. Not that it's part of the complete type, nor even
that it becomes complete with the context pointer (though that is highly
dubious at best), but the type of funcptr. It's a disgrace, simple as that.
It should either be typeless, or it should take a void* as its first
argument. void* means 'magic ahead', so it would be kinda ok.

-- 
Simen
June 10, 2013
On Monday, 10 June 2013 at 20:31:32 UTC, Simen Kjaeraas wrote:
> or it should take a void* as its first
> argument. void* means 'magic ahead', so it would be kinda ok.

This would encourage people to try something like dg.funcptr(dg.ptr, ...), which is not correct ABI-wise.

David
June 11, 2013
"Michel Fortin" <michel.fortin@michelf.ca> wrote in message news:kp4nr0$q71$1@digitalmars.com...
>
> I just find it sad that we have to use a different calling convention for member functions. I mean, it'd be much more elegant be if a member function could simply be called from a "void function(Object)" by supplying "this" as the first argument? Wouldn't it be better to adapt the ABI to fit the language rather than adapt the language to fit the ABI?
>

For D, yes, and it would be awesome.  For everything else, never ever ever.


May 27, 2014
On Mon, Jun 10, 2013 at 10:13 PM, Jacob Carlborg <doob@me.com> wrote:

> On 2013-06-10 18:34, Manu wrote:
>
>> On 11 June 2013 02:26, Jacob Carlborg <doob@me.com <mailto:doob@me.com>>
>>
>> wrote:
>>
>>     On 2013-06-10 17:40, David Nadlinger wrote:
>>
>>         Let me try to summarize it in code:
>>
>>         ---
>>         class A { void foo(); }
>>         auto memberFun = (&A.foo).funcptr;
>>
>>         auto a = new A;
>>         memberFun(a);
>>         ---
>>
>>
>>     Why is this better than a delegate?
>>
>>
>> It's not 'better', it's different.
>>
>
> class A { void foo(); }
> auto memberFun = (&A.foo).funcptr;
>
> auto a = new A;
> void delegate () dg;
> dg.funcptr = memberFun;
> dg.ptr = cast(void*) a;
> dg();
>
> The details can be hidden in a function call. Sure, a delegate could be type safe but still don't see the point.
>
> --
> /Jacob Carlborg
>

Greetings

Apologies for bringing up this year old thread.

With https://github.com/D-Programming-Language/dmd/pull/3181 getting merged, it is no longer feasible to directly assign dg.funcptr (which is not an lvalue now). The problem is that the code suggested by David also does not work.

Is there an alternative?

Regards
- Puneet


May 27, 2014
https://github.com/D-Programming-Language/dmd/pull/3181

Daniel asked me to use this. And it works.

Use something like:

union U
{
  void delegate(int) dg;
  struct
  {
    void* ptr;
    void function(int) funcptr;
  }
}
U u;
u.dg = dg;
u.funcptr = ...;
u.ptr = ...;

Regards
- Puneet


September 09, 2015
On Tuesday, 27 May 2014 at 12:21:40 UTC, d coder wrote:
> https://github.com/D-Programming-Language/dmd/pull/3181
>
> Daniel asked me to use this. And it works.
>
> Use something like:
>
> union U
> {
>   void delegate(int) dg;
>   struct
>   {
>     void* ptr;
>     void function(int) funcptr;
>   }
> }
> U u;
> u.dg = dg;
> u.funcptr = ...;
> u.ptr = ...;
>
> Regards
> - Puneet

What's the current state of this? I'm in need of such behavior for win32 interop.

I'm thinking that one can make the above code more general by using it in a mixin and automatically generating the funcptr signature:


import std.stdio;
import std.concurrency;

extern (C) int getch();
import std.string;


template FancyDelegate(O, D)
{
	const char[] FancyDelegate = "union "~O.stringof~"Delegate { "~D.stringof~" dg; struct { "~O.stringof~"* ptr; "~D.stringof.replace("delegate(", "function("~O.stringof~",").replace(",)", ")")~" funcptr; } }";	
	//const char[] FancyDelegate = "union "~O.stringof~"Delegate { "~D.stringof~" dg; struct { "~O.stringof~"* ptr; "~D.stringof.replace("delegate(", "function(")~" funcptr; } }";	
}

class X
{
	public int z = 2;
	public void foo(int x)
	{
		//writeln(this.z*x);
		writeln(x);
	}
}

void delegate(int) dg;

mixin(FancyDelegate!(X, typeof(dg)));


void main()
{

	auto xX = new X();
	XDelegate x;
	x.dg = &xX.foo;
	
	//x.dg(3);
	x.ptr = &xX;
	x.funcptr(xX, 5);
	//x.funcptr(5);

	
	getch();
}

Unfortunately this fails when entering the function. I've tried various things(passing &xX, etc..., passing nothing(the comments, etc.)

I thought a delegate, when called, was called like a member function? It seems that a delegate is some magic black box that we can't emulate in any way shape or form due to the calling conventions used?
September 09, 2015
On 6/7/2013 4:21 PM, Manu wrote:
> So from my dconf talk, I detailed a nasty hack to handle member function
> pointers in D.

https://www.digitalmars.com/articles/b68.html
September 09, 2015
On 6/10/2013 7:33 AM, Manu wrote:
> [...]

Sorry to say, your n.g. poster is back to its old tricks :-)