digitalmars.D.learn - int C function
- Ellery Newcomer (17/17) Sep 30 2011 weird error. anyone know what's going on?
- Andrej Mitrovic (19/19) Sep 30 2011 I think this is a side-effect of the new function pointer fixes, where
-
Ellery Newcomer
(15/23)
Sep 30 2011
- Ellery Newcomer (3/8) Sep 30 2011 wait, are there explicit ways to convert extern(C) funcs <-> extern(D)
- Andrej Mitrovic (7/15) Oct 01 2011 You can convert anything with an explicit cast, but it doesn't make
- Ellery Newcomer (4/23) Oct 01 2011 What what? C and D functions have different calling conventions?
- bearophile (14/22) Oct 01 2011 It's a good error message. In DMD 2.056head gives an even better error m...
- bearophile (3/4) Oct 01 2011 This seems useless. Please ignore this.
- Andrej Mitrovic (3/5) Oct 01 2011 I can't recall. Doesn't hurt to file it if you can't find it.
- travert phare.normalesup.org (Christophe) (14/32) Sep 30 2011 The compiler is actually quite explicit: puts is a C function, and X.tt
weird error. anyone know what's going on? [ellery localhost d]$ cat test.d extern(C) int puts(const char *s); class X{ property void tt(int function(const char *) xz){ } } void main(){ X x = new X(); x.tt = &puts; } [ellery localhost d]$ dmd test test.d(8): Error: function test.X.tt (int function(const const(char*)) xz) is not callable using argument types (int C function(const const(char*) s)) test.d(8): Error: cannot implicitly convert expression (& puts) of type int C function(const const(char*) s) to int function(const const(char*))
Sep 30 2011
I think this is a side-effect of the new function pointer fixes, where you now can't implicitly convert an extern(C) function to an extern(D) function by accident (and that's a good thing). But the problem is, you can't define a function with a different linkage type inline as a type parameter. You have to use an alias instead: extern (C) int puts(const char* s); alias extern(C) int function(const char*) FunPtr; class X { property void tt(FunPtr xz) { } } void main() { X x = new X(); x.tt = &puts; } (sorry for reindenting, my script does that :p)
Sep 30 2011
On 09/30/2011 08:20 PM, Andrej Mitrovic wrote:I think this is a side-effect of the new function pointer fixes, where you now can't implicitly convert an extern(C) function to an extern(D) function by accident (and that's a good thing). But the problem is, you can't define a function with a different linkage type inline as a type parameter. You have to use an alias instead: extern (C) int puts(const char* s); alias extern(C) int function(const char*) FunPtr;<code golf> template C_function(Ret,Params...){ // Params shall not have modifiers, because C has no modifiers, // therefore this is good. alias extern(C) Ret function(Params) C_function; } void input_hook(C_function!(int) hook){ ud_set_input_hook(&obj, hook); } </code golf> I presume the extern(C) is transitively applied to e.g. extern(C): ... void ud_set_input_hook(ud*, int function(ud*));
Sep 30 2011
On 09/30/2011 08:20 PM, Andrej Mitrovic wrote:I think this is a side-effect of the new function pointer fixes, where you now can't implicitly convert an extern(C) function to an extern(D) function by accident (and that's a good thing). But the problem is, you can't define a function with a different linkage type inline as a type parameter. You have to use an alias instead:wait, are there explicit ways to convert extern(C) funcs <-> extern(D) funcs?
Sep 30 2011
On 10/1/11, Ellery Newcomer <ellery-newcomer utulsa.edu> wrote:On 09/30/2011 08:20 PM, Andrej Mitrovic wrote:You can convert anything with an explicit cast, but it doesn't make much sense to cast between calling conventions types. The compiler used to allow taking an address of an extern(C) function and assigning it to an extern(D) function pointer. But this would just result in segfaults and memory corruption due to how parameters are passed. Nice code-golf, btw.I think this is a side-effect of the new function pointer fixes, where you now can't implicitly convert an extern(C) function to an extern(D) function by accident (and that's a good thing). But the problem is, you can't define a function with a different linkage type inline as a type parameter. You have to use an alias instead:wait, are there explicit ways to convert extern(C) funcs <-> extern(D) funcs?
Oct 01 2011
On 10/01/2011 08:33 AM, Andrej Mitrovic wrote:On 10/1/11, Ellery Newcomer <ellery-newcomer utulsa.edu> wrote:What what? C and D functions have different calling conventions? oh, is this for variadic argument?On 09/30/2011 08:20 PM, Andrej Mitrovic wrote:You can convert anything with an explicit cast, but it doesn't make much sense to cast between calling conventions types. The compiler used to allow taking an address of an extern(C) function and assigning it to an extern(D) function pointer. But this would just result in segfaults and memory corruption due to how parameters are passed.I think this is a side-effect of the new function pointer fixes, where you now can't implicitly convert an extern(C) function to an extern(D) function by accident (and that's a good thing). But the problem is, you can't define a function with a different linkage type inline as a type parameter. You have to use an alias instead:wait, are there explicit ways to convert extern(C) funcs <-> extern(D) funcs?Nice code-golf, btw.I think it looks horrible :)
Oct 01 2011
Ellery Newcomer:weird error. anyone know what's going on?It's a good error message. In DMD 2.056head gives an even better error message: test6.d(8): Error: function test6.X.tt (int function(const const(char*)) xz) is not callable using argument types (extern (C) int function(const const(char*) s)) test6.d(8): Error: cannot implicitly convert expression (& puts) of type extern (C) int function(const const(char*) s) to int function(const const(char*)) But the error message is not good enough yet, because "const const(char*)" needs to be written "const(char*)". ---------------------- Andrej Mitrovic:I think this is a side-effect of the new function pointer fixes, where you now can't implicitly convert an extern(C) function to an extern(D) function by accident (and that's a good thing).I think it didn't perform a conversion, it just used to produce wrong code.But the problem is, you can't define a function with a different linkage type inline as a type parameter.Is this in Bugzilla already? ---------------------- Ellery Newcomer:wait, are there explicit ways to convert extern(C) funcs <-> extern(D) funcs?Maybe a new future job for std.conv.to? (to convert a extern(C) func ponter to extern(D) func pointer). Bye, bearophile
Oct 01 2011
Maybe a new future job for std.conv.to? (to convert a extern(C) func ponter to extern(D) func pointer).This seems useless. Please ignore this. Bye, bearophile
Oct 01 2011
On 10/1/11, bearophile <bearophileHUGS lycos.com> wrote:I think it didn't perform a conversion, it just used to produce wrong code.Yes, poor wording on my part.Is this in Bugzilla already?I can't recall. Doesn't hurt to file it if you can't find it.
Oct 01 2011
Ellery Newcomer , dans le message (digitalmars.D.learn:29885), a écrit :weird error. anyone know what's going on? [ellery localhost d]$ cat test.d extern(C) int puts(const char *s); class X{ property void tt(int function(const char *) xz){ } } void main(){ X x = new X(); x.tt = &puts; } [ellery localhost d]$ dmd test test.d(8): Error: function test.X.tt (int function(const const(char*)) xz) is not callable using argument types (int C function(const const(char*) s)) test.d(8): Error: cannot implicitly convert expression (& puts) of type int C function(const const(char*) s) to int function(const const(char*))The compiler is actually quite explicit: puts is a C function, and X.tt expects a normal D function. You can solve your problem with a wrapper. Try: int cPuts(const char* s) { return puts(s); } and then : x.tt = &cPuts(); By the way, it is not very d-ish to use an "int function(const char*)". we prefer: "int delegate(const char[])". And then: | int cPuts(const char[] s) { return puts(toStringz(s)); } But it depends on what you exactly are trying to do. toStringz can be found in std.string. -- Christophe
Sep 30 2011