Thread overview | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 12, 2011 Declaring a D pointer to a C function | ||||
---|---|---|---|---|
| ||||
From a discussion related to derelict: How do you write this: ------------------------------------------------------- alias extern(C) int function(void* test) FTInitFunc; FTInitFunc FT_Init_FreeType ------------------------------------------------------- without the alias? ------------------------------------------------------- extern(C) int function(void* test) FT_Init_FreeType; ------------------------------------------------------- is not the same! both are fields containing a C function pointer, but the first field has D name mangling (_D4test16FT_Init_FreeTypePUPvZi) and the second has C name mangling: (FT_Init_FreeType, which conflicts with the C function FT_Init_FreeType) And a related question from stackoverflow: (http://stackoverflow.com/questions/6257078/casting-clutteractor-to-clutterstage) How to write this: ------------------------------------------------------- alias extern(C) void function(void*, const char*) setTitleFunc; auto clutter_stage_set_title = getSym!(setTitleFunc)("clutter_stage_set_title"); ------------------------------------------------------- without the alias? http://d.puremagic.com/issues/show_bug.cgi?id=2168 and http://d.puremagic.com/issues/show_bug.cgi?id=4288 seem to be related, extern(C) seems to work almost nowhere ;-) -- Johannes Pfau |
July 12, 2011 Re: Declaring a D pointer to a C function | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johannes Pfau | On 12/07/2011 11:36, Johannes Pfau wrote:
> From a discussion related to derelict:
> How do you write this:
> -------------------------------------------------------
> alias extern(C) int function(void* test) FTInitFunc;
> FTInitFunc FT_Init_FreeType
> -------------------------------------------------------
> without the alias?
> -------------------------------------------------------
> extern(C) int function(void* test) FT_Init_FreeType;
> -------------------------------------------------------
> is not the same!
> both are fields containing a C function pointer, but the first field
> has D name mangling (_D4test16FT_Init_FreeTypePUPvZi) and the second
> has C name mangling: (FT_Init_FreeType, which conflicts with the C
> function FT_Init_FreeType)
>
> And a related question from stackoverflow:
> (http://stackoverflow.com/questions/6257078/casting-clutteractor-to-clutterstage)
> How to write this:
> -------------------------------------------------------
> alias extern(C) void function(void*, const char*) setTitleFunc;
> auto clutter_stage_set_title =
> getSym!(setTitleFunc)("clutter_stage_set_title");
> -------------------------------------------------------
> without the alias?
>
> http://d.puremagic.com/issues/show_bug.cgi?id=2168 and
> http://d.puremagic.com/issues/show_bug.cgi?id=4288 seem to be related,
> extern(C) seems to work almost nowhere ;-)
>
>
You should declare the function pointer without the "extern(C)".
Example:
alias int function(void* test) FTInitFunc;
extern(C) int foo(void* test){ .... }
FTInitFunc foo_ptr = &foo;
This worked for me.
|
July 12, 2011 Re: Declaring a D pointer to a C function | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marco Cosentino | > You should declare the function pointer without the "extern(C)".
>
> Example:
> alias int function(void* test) FTInitFunc;
>
> extern(C) int foo(void* test){ .... }
>
> FTInitFunc foo_ptr = &foo;
>
> This worked for me.
That's a bug.
|
July 12, 2011 Re: Declaring a D pointer to a C function | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johannes Pfau | On Tue, 12 Jul 2011 05:36:15 -0400, Johannes Pfau <spam@example.com> wrote:
> From a discussion related to derelict:
> How do you write this:
> -------------------------------------------------------
> alias extern(C) int function(void* test) FTInitFunc;
> FTInitFunc FT_Init_FreeType
> -------------------------------------------------------
> without the alias?
> -------------------------------------------------------
> extern(C) int function(void* test) FT_Init_FreeType;
> -------------------------------------------------------
> is not the same!
> both are fields containing a C function pointer, but the first field
> has D name mangling (_D4test16FT_Init_FreeTypePUPvZi) and the second
> has C name mangling: (FT_Init_FreeType, which conflicts with the C
> function FT_Init_FreeType)
>
> And a related question from stackoverflow:
> (http://stackoverflow.com/questions/6257078/casting-clutteractor-to-clutterstage)
> How to write this:
> -------------------------------------------------------
> alias extern(C) void function(void*, const char*) setTitleFunc;
> auto clutter_stage_set_title =
> getSym!(setTitleFunc)("clutter_stage_set_title");
> -------------------------------------------------------
> without the alias?
extern(C) extern(C) maybe? :)
or maybe:
extern(C) int function(void * test) extern(C) FT_Init_FreeType;
Just some thoughts, it probably doesn't work.
-Steve
|
July 12, 2011 Re: Declaring a D pointer to a C function | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Steven Schveighoffer wrote: >On Tue, 12 Jul 2011 05:36:15 -0400, Johannes Pfau <spam@example.com> wrote: > >> From a discussion related to derelict: >> How do you write this: >> ------------------------------------------------------- >> alias extern(C) int function(void* test) FTInitFunc; >> FTInitFunc FT_Init_FreeType >> ------------------------------------------------------- >> without the alias? >> ------------------------------------------------------- >> extern(C) int function(void* test) FT_Init_FreeType; >> ------------------------------------------------------- >> is not the same! >> both are fields containing a C function pointer, but the first field >> has D name mangling (_D4test16FT_Init_FreeTypePUPvZi) and the second >> has C name mangling: (FT_Init_FreeType, which conflicts with the C >> function FT_Init_FreeType) >> >> And a related question from stackoverflow: (http://stackoverflow.com/questions/6257078/casting-clutteractor-to-clutterstage) How to write this: >> ------------------------------------------------------- >> alias extern(C) void function(void*, const char*) setTitleFunc; >> auto clutter_stage_set_title = >> getSym!(setTitleFunc)("clutter_stage_set_title"); >> ------------------------------------------------------- >> without the alias? > >extern(C) extern(C) maybe? :) > >or maybe: > >extern(C) int function(void * test) extern(C) FT_Init_FreeType; Nope, that doesn't work: --------------------------------- test.d(3): no identifier for declarator int C function(void* test) test.d(3): semicolon expected, not 'extern' test.d(3): no identifier for declarator FT_Init_FreeType --------------------------------- also, if that worked, shouldn't it be equal to this? --------------------------------- extern(C) int function(void* test) FT_Init_FreeType; --------------------------------- This works, but it's not what I want. Derelict needs a _field_, FT_Init_FreeType with D name mangling. So the usual {module}.{module}.FT_Init_FreeType in mangled form. This _field_ should contain a pointer to a extern(C) function. This code with alias does just that: >> ------------------------------------------------------- >> alias extern(C) int function(void* test) FTInitFunc; >> FTInitFunc FT_Init_FreeType >> ------------------------------------------------------- but it's not practical for derelict to include aliases for all functions, so the above must be accomplished without the alias. I think it should be something like this: --------------------------------- extern(C) int function(void * test) extern(D) FT_Init_FreeType; (extern(C) int function(void * test)) FT_Init_FreeType; extern(C)(int function(void * test)) FT_Init_FreeType; extern(C){int function(void * test)} FT_Init_FreeType; --------------------------------- None of these work, though. >Just some thoughts, it probably doesn't work. > >-Steve -- Johannes Pfau |
July 12, 2011 Re: Declaring a D pointer to a C function | ||||
---|---|---|---|---|
| ||||
Posted in reply to Trass3r | Trass3r wrote: >> You should declare the function pointer without the "extern(C)". >> >> Example: >> alias int function(void* test) FTInitFunc; >> >> extern(C) int foo(void* test){ .... } >> >> FTInitFunc foo_ptr = &foo; >> >> This worked for me. > >That's a bug. I agree. It looks like the above code assigns a extern(C) function pointer to a field which should only accept D function pointers. I guess if you then call foo_ptr dmd will use the D calling convention and that'll crash, at least for more complicated functions. -- Johannes Pfau |
July 12, 2011 Re: Declaring a D pointer to a C function | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johannes Pfau | On Tue, 12 Jul 2011 09:42:22 -0400, Johannes Pfau <spam@example.com> wrote:
> Steven Schveighoffer wrote:
>> On Tue, 12 Jul 2011 05:36:15 -0400, Johannes Pfau <spam@example.com>
>> wrote:
>>
>>> From a discussion related to derelict:
>>> How do you write this:
>>> -------------------------------------------------------
>>> alias extern(C) int function(void* test) FTInitFunc;
>>> FTInitFunc FT_Init_FreeType
>>> -------------------------------------------------------
>>> without the alias?
>>> -------------------------------------------------------
>>> extern(C) int function(void* test) FT_Init_FreeType;
>>> -------------------------------------------------------
>>> is not the same!
>>> both are fields containing a C function pointer, but the first field
>>> has D name mangling (_D4test16FT_Init_FreeTypePUPvZi) and the second
>>> has C name mangling: (FT_Init_FreeType, which conflicts with the C
>>> function FT_Init_FreeType)
>>>
>>> And a related question from stackoverflow:
>>> (http://stackoverflow.com/questions/6257078/casting-clutteractor-to-clutterstage)
>>> How to write this:
>>> -------------------------------------------------------
>>> alias extern(C) void function(void*, const char*) setTitleFunc;
>>> auto clutter_stage_set_title =
>>> getSym!(setTitleFunc)("clutter_stage_set_title");
>>> -------------------------------------------------------
>>> without the alias?
>>
>> extern(C) extern(C) maybe? :)
>>
>> or maybe:
>>
>> extern(C) int function(void * test) extern(C) FT_Init_FreeType;
>
> Nope, that doesn't work:
> ---------------------------------
> test.d(3): no identifier for declarator int C function(void* test)
> test.d(3): semicolon expected, not 'extern'
> test.d(3): no identifier for declarator FT_Init_FreeType
> ---------------------------------
>
> also, if that worked, shouldn't it be equal to this?
> ---------------------------------
> extern(C) int function(void* test) FT_Init_FreeType;
> ---------------------------------
> This works, but it's not what I want.
> Derelict needs a _field_, FT_Init_FreeType with D name mangling. So the
> usual {module}.{module}.FT_Init_FreeType in mangled form.
> This _field_ should contain a pointer to a extern(C) function.
>
Oh, I misread which one did which. I thought it was the opposite.
Hm... so extern(C) affects both the function pointer type and the name mangling. Interesting.
But wait, don't normal D functions have C calling convention? I thought that was one of the benefits of D's ABI?
-Steve
|
July 12, 2011 Re: Declaring a D pointer to a C function | ||||
---|---|---|---|---|
| ||||
Posted in reply to Trass3r | On 12/07/2011 13:15, Trass3r wrote:
>> You should declare the function pointer without the "extern(C)".
>>
>> Example:
>> alias int function(void* test) FTInitFunc;
>>
>> extern(C) int foo(void* test){ .... }
>>
>> FTInitFunc foo_ptr = &foo;
>>
>> This worked for me.
>
> That's a bug.
Oh, well, I forgot to mention that the function pointer is a callback that gets called by a linked C library. IMHO I don't think that the alias definition should carry with her the informations about the calling convention. This is a convention for the caller and the callee.
|
July 12, 2011 Re: Declaring a D pointer to a C function | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Tue, 12 Jul 2011 09:53:28 -0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
> But wait, don't normal D functions have C calling convention? I thought that was one of the benefits of D's ABI?
Tested it out, definitely is different. So this clearly needs to be addressed.
-Steve
|
July 12, 2011 Re: Declaring a D pointer to a C function | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | I just had a bug where a D function is implicitly converted to an extern(C) function pointer. I've had this definition: alias extern (C) void function(void* userData) PaStreamFinishedCallback; And this extern(C) function: PaError Pa_SetStreamFinishedCallback(PaStream* stream, PaStreamFinishedCallback streamFinishedCallback); And I used this callback: void StreamFinished(void* userData) { auto localData = cast(TestData*)userData; writefln("Stream Completed: %s", localData.message); } // this is where the binding takes place void main() { ...; SetStreamFinishedCallback(..., &StreamFinished); } That code is invalid. The fix is to add extern(C) to my callback: extern(C) void StreamFinished(void* userData) Is this going to be fixed any time soon? Allowing callbacks with D calling convention where a C callback is expected should be an error, and this is like the 10th time I've ran into this bug. |
Copyright © 1999-2021 by the D Language Foundation