Re: Problems with function as parameter

2017-09-22 Thread user1234 via Digitalmars-d-learn

On Friday, 22 September 2017 at 04:32:08 UTC, Josh wrote:
As an aside, in that doc it says "The .funcptr property of a 
delegate will return the function pointer value as a function 
type". So I also tried 
Mix_ChannelFinished(().funcptr); and this compiled, 
but caused a segfault when
the callback ran. What would have caused this? Is it because 
it's a C function?


No it's because in this function are used variables that are 
specific to the class instance (the this). If there weren't this 
would work, even if it's not a good idea to do that:



struct Foo
{
int a;
void needThisYeahReally(){a = 0;}
void needThisButWorkWithout(){}
}

void main()
{
Foo foo;
{
auto dg = 
dg.funcptr();
}
{
auto dg = 
// dg.funcptr(); // segfault because of access to this.a
}
}


Using a pointer to a static member function was the right thing 
to do.


Re: Problems with function as parameter

2017-09-21 Thread Josh via Digitalmars-d-learn

On Friday, 22 September 2017 at 03:26:36 UTC, Mike Parker wrote:

On Friday, 22 September 2017 at 02:22:46 UTC, Josh wrote:



src\mixer.d(80,22): Error: function pointer 
Mix_ChannelFinished (extern (C) void function(int channel)) is 
not callable using argument types (extern (C) void 
delegate(int channel))


Code:
void unmuteAfterPlaySound()
{
Mix_ChannelFinished();
}

extern (C) void channelDone(int channel)
{
unmuteMusic();
}


The error message indicates that `channelDone` is a member of a 
class or a struct. A pointer to a member function is a delegate 
(or closure), not a function pointer. Free functions, static 
nested functions, and static member functions all produce 
function pointer. Non-static member functions and non-static 
nested functions all produce delegates/closures. See the docs:


https://dlang.org/spec/function.html#closures

If you need to manipulate instance members from a C callback, 
you'll need a way to implement a mechanism to work out which 
instance you need.


Perfect, that's the info I needed. As these functions were in a 
class, setting channelDone and unmuteMusic to static worked.


As an aside, in that doc it says "The .funcptr property of a 
delegate will return the function pointer value as a function 
type". So I also tried 
Mix_ChannelFinished(().funcptr); and this compiled, 
but caused a segfault when
the callback ran. What would have caused this? Is it because it's 
a C function?


Re: Problems with function as parameter

2017-09-21 Thread Mike Parker via Digitalmars-d-learn

On Friday, 22 September 2017 at 02:32:56 UTC, Josh wrote:

Why should the binding force nothrow? I don't understand why 
you HAVE to not throw exceptions. Is it because of the C -> D 
aspect?


Yes, it's because D exceptions are not guaranteed to propagate 
through the C callstack. It works on some compiler/platforms, but 
not others. I wrote an article at Gamedev.net (which apparently 
no longer picks up the site's stylesheets) which shows one way of 
dealing with it. I've modified my approach since then (and should 
write a better article about it), but the basic idea still holds.


https://www.gamedev.net/articles/programming/general-and-gameplay-programming/d-exceptions-and-c-callbacks-r3323/


Re: Problems with function as parameter

2017-09-21 Thread Mike Parker via Digitalmars-d-learn

On Friday, 22 September 2017 at 02:32:56 UTC, Josh wrote:

Why should the binding force nothrow? I don't understand why 
you HAVE to not throw exceptions. Is it because of the C -> D 
aspect?


Yes, it's because D exceptions are not guaranteed to propagate 
through the C callstack. It works on some compiler/platforms, but 
not others. I wrote an article at Gamedev.net (which apparently 
no longer picks up the site's stylesheets) which shows one way of 
dealing with it. I've modified my approach since then (and should 
write a better article about it), but the basic idea still holds.


Re: Problems with function as parameter

2017-09-21 Thread Mike Parker via Digitalmars-d-learn

On Friday, 22 September 2017 at 02:22:46 UTC, Josh wrote:



src\mixer.d(80,22): Error: function pointer Mix_ChannelFinished 
(extern (C) void function(int channel)) is not callable using 
argument types (extern (C) void delegate(int channel))


Code:
void unmuteAfterPlaySound()
{
Mix_ChannelFinished();
}

extern (C) void channelDone(int channel)
{
unmuteMusic();
}


The error message indicates that `channelDone` is a member of a 
class or a struct. A pointer to a member function is a delegate 
(or closure), not a function pointer. Free functions, static 
nested functions, and static member functions all produce 
function pointer. Non-static member functions and non-static 
nested functions all produce delegates/closures. See the docs:


https://dlang.org/spec/function.html#closures

If you need to manipulate instance members from a C callback, 
you'll need a way to implement a mechanism to work out which 
instance you need.




Re: Problems with function as parameter

2017-09-21 Thread Josh via Digitalmars-d-learn

On Friday, 22 September 2017 at 02:18:34 UTC, Mike Parker wrote:
On Thursday, 21 September 2017 at 22:05:22 UTC, Matt Jones 
wrote:

On Thursday, 21 September 2017 at 20:21:58 UTC, Josh wrote:
I'm trying to write a callback function for SDL_mixer through 
Derelict, but this is the first time I've tried to use a 
function as a parameter, and so I think I'm just making a 
minor mistake somewhere.


[...]


Make it a C function, not a D function:

extern (C) void channelDone(int channel)
{
unmuteMusic();
}

and use & to reference the function instead of calling it:

Mix_ChannelFinished();


It should be extern(C) and, ideally, nothrow. The binding 
should be enforcing nothrow, but currently doesn't. I'll change 
that now.


Why should the binding force nothrow? I don't understand why you 
HAVE to not throw exceptions. Is it because of the C -> D aspect?


Re: Problems with function as parameter

2017-09-21 Thread Josh via Digitalmars-d-learn

On Thursday, 21 September 2017 at 22:05:22 UTC, Matt Jones wrote:

On Thursday, 21 September 2017 at 20:21:58 UTC, Josh wrote:
I'm trying to write a callback function for SDL_mixer through 
Derelict, but this is the first time I've tried to use a 
function as a parameter, and so I think I'm just making a 
minor mistake somewhere.


[...]


Make it a C function, not a D function:

extern (C) void channelDone(int channel)
{
unmuteMusic();
}

and use & to reference the function instead of calling it:

Mix_ChannelFinished();


Thanks for the help, but when I try that, I get:

src\mixer.d(80,22): Error: function pointer Mix_ChannelFinished 
(extern (C) void function(int channel)) is not callable using 
argument types (extern (C) void delegate(int channel))


Code:
void unmuteAfterPlaySound()
{
Mix_ChannelFinished();
}

extern (C) void channelDone(int channel)
{
unmuteMusic();
}


Re: Problems with function as parameter

2017-09-21 Thread Mike Parker via Digitalmars-d-learn

On Friday, 22 September 2017 at 02:18:34 UTC, Mike Parker wrote:



and use & to reference the function instead of calling it:

Mix_ChannelFinished();


To expand on this, D allows functions to be called without 
parentheses. `channelDone` is actually a function call, whereas 
in C, it's treated as a function pointer. In D, you have to take 
the address of a function just as you would any other type, hence 
``.




Re: Problems with function as parameter

2017-09-21 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 21 September 2017 at 22:05:22 UTC, Matt Jones wrote:

On Thursday, 21 September 2017 at 20:21:58 UTC, Josh wrote:
I'm trying to write a callback function for SDL_mixer through 
Derelict, but this is the first time I've tried to use a 
function as a parameter, and so I think I'm just making a 
minor mistake somewhere.


[...]


Make it a C function, not a D function:

extern (C) void channelDone(int channel)
{
unmuteMusic();
}

and use & to reference the function instead of calling it:

Mix_ChannelFinished();


It should be extern(C) and, ideally, nothrow. The binding should 
be enforcing nothrow, but currently doesn't. I'll change that now.


Re: Problems with function as parameter

2017-09-21 Thread Matt Jones via Digitalmars-d-learn

On Thursday, 21 September 2017 at 20:21:58 UTC, Josh wrote:
I'm trying to write a callback function for SDL_mixer through 
Derelict, but this is the first time I've tried to use a 
function as a parameter, and so I think I'm just making a minor 
mistake somewhere.


[...]


Make it a C function, not a D function:

extern (C) void channelDone(int channel)
{
unmuteMusic();
}

and use & to reference the function instead of calling it:

Mix_ChannelFinished();


Problems with function as parameter

2017-09-21 Thread Josh via Digitalmars-d-learn
I'm trying to write a callback function for SDL_mixer through 
Derelict, but this is the first time I've tried to use a function 
as a parameter, and so I think I'm just making a minor mistake 
somewhere.


The C SDL docs say:

// make a channelDone function
void channelDone(int channel)
{
printf("channel %d finished playing.\n", channel);
}
...
// set the callback for when a channel stops playing
Mix_ChannelFinished(channelDone);


And my D code is:

void unmuteAfterPlaySound()
{
Mix_ChannelFinished(channelDone);
}

void channelDone(int channel)
{
unmuteMusic();
}


But DMD seems to be trying to run channelDone() i.e. with no 
parameters and parentheses omitted, and is giving this error:


Error: function Mixer.channelDone (int channel) is not callable 
using argument types ()
Error: function pointer Mix_ChannelFinished (extern (C) void 
function(int channel)) is not callable using argument types 
(_error_)


Is anyone able to see what I've done wrong? Any help would be 
appreciated, thanks.