Re: Passing myself, a struct, as a C callback context

2015-03-30 Thread via Digitalmars-d-learn

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


Re: Passing myself, a struct, as a C callback context

2015-03-30 Thread Steven Schveighoffer via Digitalmars-d-learn
On 3/30/15 5:12 AM, Marc =?UTF-8?B?U2Now7x0eiI=?= schue...@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


Re: Passing myself, a struct, as a C callback context

2015-03-30 Thread Paul O'Neil via Digitalmars-d-learn
On 03/30/2015 11:32 AM, Steven Schveighoffer wrote:
 On 3/30/15 5:12 AM, Marc =?UTF-8?B?U2Now7x0eiI=?= schue...@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


Passing myself, a struct, as a C callback context

2015-03-29 Thread Paul O'Neil via Digitalmars-d-learn
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


Re: Passing myself, a struct, as a C callback context

2015-03-29 Thread weaselcat via Digitalmars-d-learn

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.


Re: Passing myself, a struct, as a C callback context

2015-03-29 Thread Paul O'Neil via Digitalmars-d-learn
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


Re: Passing myself, a struct, as a C callback context

2015-03-29 Thread ketmar via Digitalmars-d-learn
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...)

signature.asc
Description: PGP signature


Re: Passing myself, a struct, as a C callback context

2015-03-29 Thread lobo via Digitalmars-d-learn

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


Re: Passing myself, a struct, as a C callback context

2015-03-29 Thread weaselcat via Digitalmars-d-learn

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.