www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Passing myself, a struct, as a C callback context

reply Paul O'Neil <redballoon36 gmail.com> writes:
I'm registering a callback with some C code.  The simplified story is
here, but the actual code is on GitHub [1] at the end if you care.

The call looks something like this.

void register(void(*fp)(void*), void* context);

I have a class that holds state for the callback and registers itself:

final class Klass
{
    void method()
    {
        register(callback_function, &this);
    }
}

As of dmd 2.067, doing "&this" is deprecated.  Is there an idiomatic way
to do this?

[0] Actual code is at
https://github.com/todayman/dubik/blob/master/source/vibe/core/drivers/rx.d#L177
.  The msg object eventually gets passed to the registration function.

Thanks,
-- 
Paul O'Neil
Github / IRC: todayman
Mar 29 2015
next sibling parent reply "weaselcat" <weaselcat gmail.com> writes:
On Monday, 30 March 2015 at 02:53:36 UTC, Paul O'Neil wrote:

 As of dmd 2.067, doing "&this" is deprecated.
where is this documented? I don't see it in the release notes.
Mar 29 2015
parent reply Paul O'Neil <redballoon36 gmail.com> writes:
On 03/29/2015 10:57 PM, weaselcat wrote:
 On Monday, 30 March 2015 at 02:53:36 UTC, Paul O'Neil wrote:
 
 As of dmd 2.067, doing "&this" is deprecated.
where is this documented? I don't see it in the release notes.
I don't see it in the release notes either, but it's happening. Maybe it's an instance of a more general thing? -- Paul O'Neil Github / IRC: todayman
Mar 29 2015
parent "weaselcat" <weaselcat gmail.com> writes:
On Monday, 30 March 2015 at 03:02:07 UTC, Paul O'Neil wrote:
 On 03/29/2015 10:57 PM, weaselcat wrote:
 On Monday, 30 March 2015 at 02:53:36 UTC, Paul O'Neil wrote:
 
 As of dmd 2.067, doing "&this" is deprecated.
where is this documented? I don't see it in the release notes.
I don't see it in the release notes either, but it's happening. Maybe it's an instance of a more general thing?
if it works in 2.066 you should submit a bug report, either this shouldn't be a deprecation or it should be in the release notes.
Mar 29 2015
prev sibling next sibling parent "lobo" <swamplobo gmail.com> writes:
On Monday, 30 March 2015 at 02:53:36 UTC, Paul O'Neil wrote:
 I'm registering a callback with some C code.  The simplified 
 story is
 here, but the actual code is on GitHub [1] at the end if you 
 care.

 The call looks something like this.

 void register(void(*fp)(void*), void* context);

 I have a class that holds state for the callback and registers 
 itself:

 final class Klass
 {
     void method()
     {
         register(callback_function, &this);
     }
 }

 As of dmd 2.067, doing "&this" is deprecated.  Is there an 
 idiomatic way
 to do this?

 [0] Actual code is at
 https://github.com/todayman/dubik/blob/master/source/vibe/core/drivers/rx.d#L177
 .  The msg object eventually gets passed to the registration 
 function.

 Thanks,
This is only deprecated for class not struct. This code below works fine: --- import std.stdio; extern(C) void f2(void* ins) { auto s = cast(S*)(ins); writefln("f2():%s", s); writefln("f2():%s", *s); } void f1(void* ins) { auto s = cast(S*)(ins); writefln("f1():%s", s); writefln("f1():%s", *s); } struct S { // <<-- change to "class" to get deprecated message int value = 10; void f() { f1(&this); f2(&this); } } void main() { auto s = S(); s.f(); } --- bye, lobo
Mar 29 2015
prev sibling next sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
On Sun, 29 Mar 2015 22:53:35 -0400, Paul O'Neil wrote:

 I'm registering a callback with some C code.  The simplified story is
 here, but the actual code is on GitHub [1] at the end if you care.
=20
 The call looks something like this.
=20
 void register(void(*fp)(void*), void* context);
=20
 I have a class that holds state for the callback and registers itself:
=20
 final class Klass {
     void method()
     {
         register(callback_function, &this);
     }
 }
=20
 As of dmd 2.067, doing "&this" is deprecated.  Is there an idiomatic way
 to do this?
=20
 [0] Actual code is at
 https://github.com/todayman/dubik/blob/master/source/vibe/core/drivers/
rx.d#L177
 .  The msg object eventually gets passed to the registration function.
=20
 Thanks,
you still can cast `this` to void pointer: `cast(void*)this` but beware of possible `opCast` overloads for `void*` (there are no in=20 stdlib, but...)=
Mar 29 2015
prev sibling parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Monday, 30 March 2015 at 02:53:36 UTC, Paul O'Neil wrote:
 I'm registering a callback with some C code.  The simplified 
 story is
 here, but the actual code is on GitHub [1] at the end if you 
 care.

 The call looks something like this.

 void register(void(*fp)(void*), void* context);

 I have a class that holds state for the callback and registers 
 itself:

 final class Klass
 {
     void method()
     {
         register(callback_function, &this);
     }
 }
`this` is already a reference. You're taking the address of that reference. A simple cast should work: `cast(void*) this`.
Mar 30 2015
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 3/30/15 5:12 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net>" 
wrote:
 On Monday, 30 March 2015 at 02:53:36 UTC, Paul O'Neil wrote:
 I'm registering a callback with some C code.  The simplified story is
 here, but the actual code is on GitHub [1] at the end if you care.

 The call looks something like this.

 void register(void(*fp)(void*), void* context);

 I have a class that holds state for the callback and registers itself:

 final class Klass
 {
     void method()
     {
         register(callback_function, &this);
     }
 }
`this` is already a reference. You're taking the address of that reference. A simple cast should work: `cast(void*) this`.
To build on this further, &this for a class is actually taking a local stack reference, this is why it's not allowed. And technically, cast(void*) this is dangerous in the general case because opCast can be overridden. If you absolutely need to get a pointer to a class reference, you would need to do this: auto x = this; auto p = &x; For example, for a foolproof implementation of converting a class reference to void *, you would need to do: auto x = this; auto p = *(cast(void **)&x); I wonder if those who made this change thought of this problem? -Steve
Mar 30 2015
parent Paul O'Neil <redballoon36 gmail.com> writes:
On 03/30/2015 11:32 AM, Steven Schveighoffer wrote:
 On 3/30/15 5:12 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net>"
 wrote:
 `this` is already a reference. You're taking the address of that
 reference. A  simple cast should work: `cast(void*) this`.
To build on this further, &this for a class is actually taking a local stack reference, this is why it's not allowed. And technically, cast(void*) this is dangerous in the general case because opCast can be overridden. If you absolutely need to get a pointer to a class reference, you would need to do this: auto x = this; auto p = &x; For example, for a foolproof implementation of converting a class reference to void *, you would need to do: auto x = this; auto p = *(cast(void **)&x); I wonder if those who made this change thought of this problem? -Steve
Thanks for the explanation. This makes a lot of sense - I forgot that "ref" actually means "special pointer." Luckily, I don't plan on overriding opCast! -- Paul O'Neil Github / IRC: todayman
Mar 30 2015