Thread overview | |||||
---|---|---|---|---|---|
|
November 01, 2010 How to use a member function (delegate) as a function pointer | ||||
---|---|---|---|---|
| ||||
Hello. I'm new to D. It's been a long time since I've coded anything with classes. Please excuse my ignorance. Here's a very simplified version of what I'm trying to do: import std.c.linux.linux; import std.stdio; class FOO { this() { sa.sa_handler = &handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sigaction(SIGALRM, &sa, null); } ~this() { sa.sa_handler = SIG_DFL; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sigaction(SIGALRM, &sa, null); } private: sigaction_t sa; void handler(int signal) { writeln("Got an alarm signal."); } } Is there a way to do it without removing handler() from the class? When I try compiling, I get: Error: cannot implicitly convert expression (&this.handler) of type void delegate(int signal) to void C function(int). Thank you, - Peter |
November 01, 2010 Re: How to use a member function (delegate) as a function pointer | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peter Federighi | On Mon, 01 Nov 2010 05:27:06 +0300, Peter Federighi <pfederighi@yahoo.com> wrote:
> Hello. I'm new to D. It's been a long time since I've coded anything with
> classes. Please excuse my ignorance.
>
> Here's a very simplified version of what I'm trying to do:
>
> import std.c.linux.linux;
> import std.stdio;
> class FOO
> {
> this()
> {
> sa.sa_handler = &handler;
> sigemptyset(&sa.sa_mask);
> sa.sa_flags = SA_RESTART;
> sigaction(SIGALRM, &sa, null);
> }
>
> ~this()
> {
> sa.sa_handler = SIG_DFL;
> sigemptyset(&sa.sa_mask);
> sa.sa_flags = SA_RESTART;
> sigaction(SIGALRM, &sa, null);
> }
>
> private:
> sigaction_t sa;
>
> void handler(int signal)
> {
> writeln("Got an alarm signal.");
> }
> }
>
>
> Is there a way to do it without removing handler() from the class? When I try
> compiling, I get: Error: cannot implicitly convert expression (&this.handler)
> of type void delegate(int signal) to void C function(int).
>
> Thank you,
> - Peter
No, unfortunately not. A delegate is a function pointer PLUS 'this'. The C API you are using allows providing function only, without a context. As such, you need to store 'this' pointer somewhere else. It is usually done by means of of a special userData variable which is additionally passed to the callback (looks like we are out of luck this time), or storing it in a global variable:
Foo foo;
void externalHandler(int signal)
{
assert(foo !is null);
foo.handler(signal);
}
class Foo
{
this() {
assert(foo is null);
foo = this;
sa.sa_handler = &externalHandler;
// ...
}
~this() {
assert(foo is this);
foo = null;
// ...
}
// ...
}
|
November 01, 2010 Re: How to use a member function (delegate) as a function pointer | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peter Federighi | "Peter Federighi" <pfederighi@yahoo.com> wrote in message news:ial8hq$2137$1@digitalmars.com... > Is there a way to do it without removing handler() from the class? When I > try > compiling, I get: Error: cannot implicitly convert expression > (&this.handler) > of type void delegate(int signal) to void C function(int). Yes, but it requires some nasty code. (Not tested on anything except windows) http://yebblies.com/thunk.d (Also not tested) import yebblies.thunk.d; import std.c.linux.linux; import std.stdio; class FOO { this() { th = thunk!"C"(&handler); sa.sa_handler = th.ptr; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sigaction(SIGALRM, &sa, null); } ~this() { sa.sa_handler = SIG_DFL; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sigaction(SIGALRM, &sa, null); } private: sigaction_t sa; typeof(thunk!"C"(&handler)) th; void handler(int signal) { writeln("Got an alarm signal."); } } It basically gets around the restriction by writing some code into memory that passes the delegate params in unused registers. I don't even know if the page allocation code works on anything except windows. Daniel |
Copyright © 1999-2021 by the D Language Foundation