Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
March 30, 2015 Passing myself, a struct, as a C callback context | ||||
---|---|---|---|---|
| ||||
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 |
March 30, 2015 Re: Passing myself, a struct, as a C callback context | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul O'Neil | 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.
|
March 30, 2015 Re: Passing myself, a struct, as a C callback context | ||||
---|---|---|---|---|
| ||||
Posted in reply to weaselcat | 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 |
March 30, 2015 Re: Passing myself, a struct, as a C callback context | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul O'Neil | 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.
|
March 30, 2015 Re: Passing myself, a struct, as a C callback context | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul O'Neil | 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
|
March 30, 2015 Re: Passing myself, a struct, as a C callback context | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul O'Neil Attachments: | 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. > > 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, you still can cast `this` to void pointer: `cast(void*)this` but beware of possible `opCast` overloads for `void*` (there are no in stdlib, but...) |
March 30, 2015 Re: Passing myself, a struct, as a C callback context | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul O'Neil | 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`.
|
March 30, 2015 Re: Passing myself, a struct, as a C callback context | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | 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
|
March 31, 2015 Re: Passing myself, a struct, as a C callback context | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 |
Copyright © 1999-2021 by the D Language Foundation