digitalmars.D.learn - Unable to pass a D function member to a C callback
- Luh (43/43) Nov 02 2019 Hello,
- Stefan Koch (3/47) Nov 02 2019 you are missing a static in your member function's signature.
- Luh (22/78) Nov 02 2019 My problem is, that the onProcess function should not be static
- Alex (8/52) Nov 02 2019 This is because onProcessCb is a member of an object. Therefore,
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*); } -----
Nov 02 2019
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.
Nov 02 2019
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: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. :(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.
Nov 02 2019
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.
Nov 02 2019
On Saturday, 2 November 2019 at 19:55:58 UTC, Dennis wrote:On Saturday, 2 November 2019 at 19:42:54 UTC, Luh wrote:Yup that's it ! Many thanks !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.
Nov 02 2019
On Saturday, 2 November 2019 at 20:42:29 UTC, Luh wrote:Yup that's it ! Many thanks !One word of warning: ensure the C library does not have the only reference to your Game class instance, or the garbage collector might deallocate it since it does not scan threads created by C libraries. See: https://dlang.org/spec/garbage.html#gc_foreign_obj
Nov 02 2019
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*); } -----This is because onProcessCb is a member of an object. Therefore, it carries also the information about the context, which includes e.g. all members of the class. Due to this onProcessCb is a delegate, which is something different from a function, cf. https://dlang.org/spec/function.html#closures So, there is a type mismatch.
Nov 02 2019