Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
August 09, 2017 delegates/lambas do not pick up calling convention | ||||
---|---|---|---|---|
| ||||
given somethign like Threads.threadsAddIdle which takes an extern(C) int (void*) we can't seem to do threadsAddIdle((void*) { }, null); nor because D complains is not the correct type nor can we do delegate(void*) or extern(C) delegate(void*) {} and have to resort to verbosity to get it to work. Is there a way around that? Why can't D realize that an inline lambda should use the same calling convention? There is no harm in doing so. Maybe I'm doing it wrong: I've tried import gdk.Threads; alias DD = static extern(C) int delegate(void*); auto x = (void*) { return 1; }; gdk.Threads.threadsAddIdle(x, null); which gives the error (extern (C) int function(void* userData) funct, void* data) is not callable using argument types int function(void* _param_0) pure nothrow @nogc @safe, typeof(null)) While one can do something like gdk.Threads.threadsAddIdle(cast(GSourceFunc)(void* data) { return 1; }, null); which seems to work but the cast seems superfluous as D should be able to implicitly figure that out since it's an inline delegate. |
August 09, 2017 Re: delegates/lambas do not pick up calling convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johnson Jones | On 8/9/17 7:52 PM, Johnson Jones wrote:
> given somethign like Threads.threadsAddIdle
>
> which takes an extern(C) int (void*)
>
> we can't seem to do
>
> threadsAddIdle((void*) { }, null);
Because D tries to avoid situations where the type depends on the usage. The implied type is based solely on the expression (in most cases, there are a few cases where it is affected by usage).
FYI I also code in swift, and I run into situations all the time where the compiler can't figure out types for a statement because it hits some weird corner case that causes too much recursion in the compiler. In those cases, the compiler says "please split up your statement into multiple lines". So I'm kind of glad D doesn't go this route, as nice as it is conceptually.
-Steve
|
August 10, 2017 Re: delegates/lambas do not pick up calling convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johnson Jones | On 08/10/2017 01:52 AM, Johnson Jones wrote:
> I've tried
>
> import gdk.Threads;
> alias DD = static extern(C) int delegate(void*);
> auto x = (void*)
> {
> return 1;
> };
> gdk.Threads.threadsAddIdle(x, null);
1) You probably meant to apply `DD` to `x`.
2) `x` must be a `function`, not a `delegate`.
3) (optional) `static` is not needed.
So:
----
import gdk.Threads;
alias DD = extern(C) int function(void*);
DD x = (void*)
{
return 1;
};
gdk.Threads.threadsAddIdle(x, null);
----
|
August 10, 2017 Re: delegates/lambas do not pick up calling convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johnson Jones | On 10.08.2017 01:52, Johnson Jones wrote: > given somethign like Threads.threadsAddIdle > > which takes an extern(C) int (void*) > > we can't seem to do > > threadsAddIdle((void*) { }, null); I think this is a compiler bug. Try: threadsAddIdle((x){ }, null); It seems that the calling convention is deduced only if the parameter type needs to be deduced too. https://issues.dlang.org/show_bug.cgi?id=17739 |
August 10, 2017 Re: delegates/lambas do not pick up calling convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johnson Jones | On Wednesday, 9 August 2017 at 23:52:00 UTC, Johnson Jones wrote:
> extern(C) delegate(void*) {}
You should very rarely use extern(C) delegate... delegate is a D type, so the C function is almost certainly not actually receiving it.
Only time you'd want an extern(C) using D types like delegates, arrays, strings, etc., is if the receiver is actually also written in D.
idk if this would fix your problem, but it should be changed regardless.
|
August 10, 2017 Re: delegates/lambas do not pick up calling convention | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On 10.08.2017 15:22, Adam D. Ruppe wrote:
> On Wednesday, 9 August 2017 at 23:52:00 UTC, Johnson Jones wrote:
>> extern(C) delegate(void*) {}
>
> You should very rarely use extern(C) delegate... delegate is a D type, so the C function is almost certainly not actually receiving it.
>
> Only time you'd want an extern(C) using D types like delegates, arrays, strings, etc., is if the receiver is actually also written in D.
>
> idk if this would fix your problem, but it should be changed regardless.
gdk is actually using a function with arguments of type (extern(C) int function(void*),void*).
Anyway, I think there are use cases for extern(C) delegates too, along the following lines:
alias D=extern(C) int delegate(int);
struct F(S,T...){ // this struct is compatible with C
void* ptr;
extern(C) S function(void*,T) funptr;
auto opCall(T args){
return funptr(ptr,args);
}
}
void main(){
int y=2;
D dg=(x)=>x+y;
auto f=*cast(F!(int,int)*)&dg;
import std.stdio;
writeln(f(3));
}
|
Copyright © 1999-2021 by the D Language Foundation