0

In an attempt to wrap a C function taking callbacks, I encountered the problem of member functions being seen as delegates. The C function wouldn't take delegates, so I settled on something else instead:

extern(C) void onMouse(void delegate(int, int, int) nothrow callback)
{
    glfwSetMouseButtonCallback(handle,
        function void (GLFWwindow* h, int button, int action, int mods) nothrow
        {
            callback(button, action, mods);
        }
    );
}

As you can see, I'm passing to the callback setting function a function literal calling a delegate (which would be the member function I pass here).

However, it doesn't end up as I expect:

Error: function pointer glfwSetMouseButtonCallback (GLFWwindow*, extern (C) void function(GLFWwindow*, int, int, int) nothrow) is not callable using argument types (GLFWwindow*, void delegate(GLFWwindow* h, int button, int action, int mods) nothrow @system)

In the error, it shows the second parameter as being as the type void delegate.

So. My question is: why does this happen? As you can clearly see, it says function void in the code.

NOTE: I've seen this: Pass delegates to external C functions in D. The solution is apparently a hack. But I will try it if I cannot find a workaround on the internet.

Community
  • 1
  • 1
hpm
  • 1,202
  • 13
  • 34
  • Your main problem seems to be the *linkage* for the function - "C" and C++. To me it is not very clear what you *want* it to be - is "delegate" supposed to be of C or C++ linkage? – tofro Apr 10 '16 at 08:57
  • @tofro I'm afraid I do not understand. The delegate literal is just a function literal with a 'this' attached, making it incompatible with C and (for some reason) unable to be translated into a function literal with ease. – hpm Apr 10 '16 at 09:01
  • Watch the compiler messages closely. You have told it `glfwSetMouseButtonCallback ()`would take an `extern "C"` function pointer as second argument. But you are handing in a C++ function pointer (`delegate`) instead. Those two types are not compatible. – tofro Apr 10 '16 at 09:33
  • So, if I did `extern(C) void function(GLFWwindow*, int, int, int) cb = (h, button, action, mods) { callback(button, action, mods); };` then why doesn't that work either? and are you confusing D with C++? – hpm Apr 10 '16 at 10:09
  • 1
    I don't think this would compile anyway because your "function" is accessing a local variable, which means it is necessarily a delegate (function pointers can not access local variables, including parameters passed to the outside function). The error should probably say that instead of pretending it is a delegate, but regardless, this code should indeed be an error. – Adam D. Ruppe Apr 10 '16 at 13:21
  • @AdamD.Ruppe Really? Before I had to use delegates, I passed a function literal that did access a local variable to the C function... and everything worked fine. Or am I misunderstanding what you mean? Anyways, I suppose that proved my thought that something was going on behind my back. – hpm Apr 10 '16 at 13:54
  • Can you post some of the code? If it was local and static, that's different. But the reason it is a delegate is local variables can change on each run of the function, so they need a pointer to the right data block. A delegate has that, a function doesn't. – Adam D. Ruppe Apr 10 '16 at 18:44
  • @AdamD.Ruppe Oh, I think I get what you mean. My previous code was actually accessing static variables, which seems to explain some of the trouble I was having earlier with local variables. And the trouble was because it was somehow implicitly converted or something. – hpm Apr 10 '16 at 22:46

1 Answers1

1

Even though you declare it as function, it cannot be. It relies on the parameter you pass to onMouse. That parameter is a local variable, and accessing them in a function body makes them a delegate. All you can do is change the parameter to function and pass it with &callback (you'd need to add GLFWwindow as parameter then).

Alternatively, you can create a global list in which this callback puts events which you can then process in your main loop.

weltensturm
  • 2,164
  • 16
  • 17
  • I really think that D should not implicitly convert the function literal into a delegate literal. That gave me quite a lot of confusion. – hpm Apr 12 '16 at 06:11