Unable to pass a D function member to a C callback
Hello, When trying to pass a D function to the C callback, the compiler says: 'Error: cannot implicitly convert expression &this.onProcessCb of type extern (C) bool delegate(const(short*) a, ulong b, void* c) to extern (C) bool function(const(short*), ulong, void*' because my function is member of a class (compiles when the function is out of the class). Is there any way to say to solve this ? The wiki isn't very clear about the C callbacks: https://dlang.org/spec/interfaceToC.html#callbacks C code: typedef bool (*onProcessCallback)(const short*, size_t, void*); D Code: - class Game { onProcessCallback m_onProcessCb; this() { m_onProcessCb = &onProcessCb; // Error here } void onProcess() { // ... } extern(C) bool onProcessCb(const short* a, size_t b, void* c) { onProcess(); return true; } } private extern(C) { // Should call onProcess() when executed by the C lib alias onProcessCallback = bool function(const short*, size_t, void*); } -
Re: Unable to pass a D function member to a C callback
On Saturday, 2 November 2019 at 18:31:28 UTC, Stefan Koch wrote: On Saturday, 2 November 2019 at 17:49:09 UTC, Luh wrote: Hello, When trying to pass a D function to the C callback, the compiler says: 'Error: cannot implicitly convert expression &this.onProcessCb of type extern (C) bool delegate(const(short*) a, ulong b, void* c) to extern (C) bool function(const(short*), ulong, void*' because my function is member of a class (compiles when the function is out of the class). Is there any way to say to solve this ? The wiki isn't very clear about the C callbacks: https://dlang.org/spec/interfaceToC.html#callbacks C code: typedef bool (*onProcessCallback)(const short*, size_t, void*); D Code: - class Game { onProcessCallback m_onProcessCb; this() { m_onProcessCb = &onProcessCb; // Error here } void onProcess() { // ... } extern(C) bool onProcessCb(const short* a, size_t b, void* c) { onProcess(); return true; } } private extern(C) { // Should call onProcess() when executed by the C lib alias onProcessCallback = bool function(const short*, size_t, void*); } - you are missing a static in your member function's signature. The callback is not providing a this pointer. My problem is, that the onProcess function should not be static because it uses a variable inside the class. like: - class Game { private short[] m_a; void onProcess(short[] a) { m_a ~= a; // ... } extern(C) bool onProcessCb(const short* a, size_t b, void* c) { onProcess(); return true; } } - So I think I just can't. :(
Re: Unable to pass a D function member to a C callback
On Saturday, 2 November 2019 at 19:55:58 UTC, Dennis wrote: On Saturday, 2 November 2019 at 19:42:54 UTC, Luh wrote: So I think I just can't. :( Is that `void* c` in the callback a context pointer by any chance? That's a common thing in C callbacks precisely for purposes like this. You can cast your class to a void* when you register the callback and in the callback function cast it back to a class and call process on that. I don't know what C library you're working with so can't give you specifics. Yup that's it ! Many thanks !
Linker anomalies
Hey there, I figured out some strange behavior ; #1 It seems that the linker doesn't check for the function declared twice first. Instead, it says: "Error: class app.Child use of app.Parent.foo() is hidden by Child; use alias foo = Parent.foo; to introduce base class overload set" but when we call it ( p.foo() ), then it returns the correct error message. #2 The template update() compiles fine until we call it. Bizarre, isn't it ? code: --- void main() { auto p = new Parent(); // Shows the wrong error message until uncommented //p.foo(); // Compiles when commented //update(p); } class Child : Parent { override void foo() { } } class Parent { void foo() { } void foo() { } } void update(T)(T object) if(is(T == Parent)) { static if (is(T == Parent)) { // Shouldn't compile ObjectThatDoesntExists.bar(T); } } --- Is this a bug ?
Re: Linker anomalies
On Thursday, 7 November 2019 at 18:45:21 UTC, Ali Çehreli wrote: On 11/07/2019 04:14 AM, Luh wrote: It's not the linker but the "compiler" that is concerned about these things. [...] Oops :o That's an important warning where the programmer can get surprising results depending on whether the object is used through the Parent interface or the Child interface. > [...] error message. [...] It would be clever to show the correct error message :) (I spend 1 hour to find what was the problem haha. I hope the others newbies won't make the same mistake) Apparently, the compiler does not check whether an overload set has ambiguities until actual use. I suspect the opposite would slow dow compilation and cause frustration in some cases. [...] Thanks for the tips.