Unable to pass a D function member to a C callback

2019-11-02 Thread Luh via Digitalmars-d-learn

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

2019-11-02 Thread Luh via Digitalmars-d-learn

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

2019-11-02 Thread Luh via Digitalmars-d-learn

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

2019-11-07 Thread Luh via Digitalmars-d-learn

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

2019-11-07 Thread Luh via Digitalmars-d-learn

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.