digitalmars.D.learn - Declaring a D pointer to a C function
- Johannes Pfau (30/30) Jul 12 2011 =46rom a discussion related to derelict:
- Marco Cosentino (7/34) Jul 12 2011 You should declare the function pointer without the "extern(C)".
- Trass3r (1/7) Jul 12 2011 That's a bug.
- Johannes Pfau (7/18) Jul 12 2011 I agree. It looks like the above code assigns a extern(C) function
- Marco Cosentino (5/16) Jul 12 2011 Oh, well, I forgot to mention that the function pointer is a callback
- Steven Schveighoffer (6/30) Jul 12 2011 extern(C) extern(C) maybe? :)
- Johannes Pfau (28/64) Jul 12 2011 Nope, that doesn't work:
- Steven Schveighoffer (7/56) Jul 12 2011 Oh, I misread which one did which. I thought it was the opposite.
- Steven Schveighoffer (5/7) Jul 12 2011 Tested it out, definitely is different. So this clearly needs to be
- Andrej Mitrovic (20/20) Jul 12 2011 I just had a bug where a D function is implicitly converted to an
- Trass3r (1/4) Jul 12 2011 http://d.puremagic.com/issues/show_bug.cgi?id=3797
- Andrej Mitrovic (2/6) Jul 12 2011 Thanks, I'm voting this up
- Andrej Mitrovic (2/2) Jul 12 2011 Oh there's a pull already, this is great.
- Daniel Murphy (4/7) Jul 13 2011 What, the bug that annoyed me so much I fixed it myself? Yeah, this sho...
- Andrej Mitrovic (4/11) Jul 13 2011 Thanks! I've literally lost an entire day once when I was just
- Daniel Murphy (4/7) Jul 13 2011 It's worse than just calling conventions - try changing the parameter ty...
- Steven Schveighoffer (6/14) Jul 13 2011 Yeah, examining the assembly, a major difference is that D passes one
=46rom 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-clutter= stage) How to write this: ------------------------------------------------------- alias extern(C) void function(void*, const char*) setTitleFunc; auto clutter_stage_set_title =3D getSym!(setTitleFunc)("clutter_stage_set_title"); ------------------------------------------------------- without the alias? http://d.puremagic.com/issues/show_bug.cgi?id=3D2168 and http://d.puremagic.com/issues/show_bug.cgi?id=3D4288 seem to be related, extern(C) seems to work almost nowhere ;-) --=20 Johannes Pfau
Jul 12 2011
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.
Jul 12 2011
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.
Jul 12 2011
Trass3r wrote: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 PfauYou 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.
Jul 12 2011
On 12/07/2011 13:15, Trass3r wrote: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.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.
Jul 12 2011
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
Jul 12 2011
Steven Schveighoffer wrote:On Tue, 12 Jul 2011 05:36:15 -0400, Johannes Pfau <spam example.com> wrote: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: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;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.------------------------------------------------------- alias extern(C) int function(void* test) FTInitFunc; FTInitFunc FT_Init_FreeType -------------------------------------------------------Just some thoughts, it probably doesn't work. -Steve-- Johannes Pfau
Jul 12 2011
On Tue, 12 Jul 2011 09:42:22 -0400, Johannes Pfau <spam example.com> wrote:Steven Schveighoffer wrote: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? -SteveOn Tue, 12 Jul 2011 05:36:15 -0400, Johannes Pfau <spam example.com> wrote: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.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;
Jul 12 2011
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
Jul 12 2011
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.
Jul 12 2011
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.http://d.puremagic.com/issues/show_bug.cgi?id=3797
Jul 12 2011
On 7/12/11, Trass3r <un known.com> wrote:Thanks, I'm voting this upIs 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.http://d.puremagic.com/issues/show_bug.cgi?id=3797
Jul 12 2011
Oh there's a pull already, this is great. https://github.com/D-Programming-Language/dmd/pull/96
Jul 12 2011
"Andrej Mitrovic" <andrej.mitrovich gmail.com> wrote in message news:mailman.1569.1310506439.14074.digitalmars-d-learn puremagic.com...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.What, the bug that annoyed me so much I fixed it myself? Yeah, this should be gone by the next release.
Jul 13 2011
On 7/13/11, Daniel Murphy <yebblies nospamgmail.com> wrote:"Andrej Mitrovic" <andrej.mitrovich gmail.com> wrote in message news:mailman.1569.1310506439.14074.digitalmars-d-learn puremagic.com...Thanks! I've literally lost an entire day once when I was just starting using D and C together and had a calling convention mismatch. :xIs 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.What, the bug that annoyed me so much I fixed it myself? Yeah, this should be gone by the next release.
Jul 13 2011
"Andrej Mitrovic" <andrej.mitrovich gmail.com> wrote in message news:mailman.1607.1310570915.14074.digitalmars-d-learn puremagic.com...Thanks! I've literally lost an entire day once when I was just starting using D and C together and had a calling convention mismatch. :xIt's worse than just calling conventions - try changing the parameter types! (or basically anything except the return type)
Jul 13 2011
On Wed, 13 Jul 2011 11:32:50 -0400, Daniel Murphy <yebblies nospamgmail.com> wrote:"Andrej Mitrovic" <andrej.mitrovich gmail.com> wrote in message news:mailman.1607.1310570915.14074.digitalmars-d-learn puremagic.com...Yeah, examining the assembly, a major difference is that D passes one parameter in a register, whereas C pushes it on the stack. This means you are going to have off-by-one corruption any time you access a parameter. -SteveThanks! I've literally lost an entire day once when I was just starting using D and C together and had a calling convention mismatch. :xIt's worse than just calling conventions - try changing the parameter types! (or basically anything except the return type)
Jul 13 2011