digitalmars.D.learn - Callbacks and interfacing with C
- Nick Sabalausky (12/12) Oct 30 2012 Ok, a C function pointer like this:
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (13/25) Oct 30 2012 You generally do it this way:
- Nick Sabalausky (13/45) Oct 30 2012 Hmm, that leads me to another Q:
- bearophile (7/9) Oct 30 2012 A general comment: if you are not sure of the answer, then the
- Andrej Mitrovic (18/20) Oct 30 2012 All of them.
- Jacob Carlborg (17/34) Oct 30 2012 It doesn't leak into local declarations in a function:
Ok, a C function pointer like this: struct MyStruct{ int (*foo)(int); }; Translates to D as this: struct MyStruct{ int function(int) foo; } But what about calling conventions? There isn't any "int extern(C) function(int)" is there? Not sure if that would even make sense. So do you just make sure that whatever func you assign to it is an extern(C)? Or something else?
Oct 30 2012
On 30-10-2012 11:13, Nick Sabalausky wrote:Ok, a C function pointer like this: struct MyStruct{ int (*foo)(int); }; Translates to D as this: struct MyStruct{ int function(int) foo; } But what about calling conventions? There isn't any "int extern(C) function(int)" is there? Not sure if that would even make sense. So do you just make sure that whatever func you assign to it is an extern(C)? Or something else?You generally do it this way: alias extern (C) int function(int) MyFn; struct MyStruct { MyFn foo; } This makes sure the calling convention is correct. In general, calling convention is part of both the function signature and function pointer type - function pointers just default to extern (D). -- Alex Rønne Petersen alex lycus.org http://lycus.org
Oct 30 2012
On Tue, 30 Oct 2012 11:15:55 +0100 Alex R=F8nne Petersen <alex lycus.org> wrote:On 30-10-2012 11:13, Nick Sabalausky wrote:Hmm, that leads me to another Q: extern(C): // <-- Note this =20 alias int function(int) MyFn; struct MyStruct { MyFn foo1; int function(int) foo2; } void bar(int function(int) foo3) {...} Which, if any, of foo1/foo2/foo3 are extern(C)? (I know bar definitely is.)Ok, a C function pointer like this: struct MyStruct{ int (*foo)(int); }; Translates to D as this: struct MyStruct{ int function(int) foo; } But what about calling conventions? There isn't any "int extern(C) function(int)" is there? Not sure if that would even make sense. So do you just make sure that whatever func you assign to it is an extern(C)? Or something else?=20 You generally do it this way: =20 alias extern (C) int function(int) MyFn; =20 struct MyStruct { MyFn foo; } =20 This makes sure the calling convention is correct. In general, calling convention is part of both the function signature and function pointer type - function pointers just default to extern (D). =20
Oct 30 2012
Nick Sabalausky:Which, if any, of foo1/foo2/foo3 are extern(C)? (I know bar definitely is.)A general comment: if you are not sure of the answer, then the programmer that will read your code will probably have similar problems. So in such cases it's better to try to not write that code. Bye, bearophile
Oct 30 2012
On 10/30/12, Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> wrote:Which, if any, of foo1/foo2/foo3 are extern(C)? (I know bar definitely is.)All of them. void main() { pragma(msg, MyFn); pragma(msg, typeof(MyStruct.foo2)); pragma(msg, typeof(bar)); } extern (C) int function(int) extern (C) int function(int) extern (C) void(extern (C) int function(int) foo3) extern (C) int function(int) extern (C) int function(int) extern (C) void(extern (C) int function(int) foo3) It's because extern(C): leaks everywhere, whether on purpose or not. It can be a benefit for writing shorter code, but when reading such code it's easy to forget to check for an extern(C): declaration at the top and just wrongly assume that it's all extern(D).
Oct 30 2012
On 2012-10-30 18:44, Andrej Mitrovic wrote:All of them. void main() { pragma(msg, MyFn); pragma(msg, typeof(MyStruct.foo2)); pragma(msg, typeof(bar)); } extern (C) int function(int) extern (C) int function(int) extern (C) void(extern (C) int function(int) foo3) extern (C) int function(int) extern (C) int function(int) extern (C) void(extern (C) int function(int) foo3) It's because extern(C): leaks everywhere, whether on purpose or not. It can be a benefit for writing shorter code, but when reading such code it's easy to forget to check for an extern(C): declaration at the top and just wrongly assume that it's all extern(D).It doesn't leak into local declarations in a function: extern (C): void foo () { alias void function () Foo; void function (int) a; auto b = cast(void function ()) a; pragma(msg, Foo); pragma(msg, typeof(a)); pragma(msg, typeof(b)); } void function() void function(int) void function() -- /Jacob Carlborg
Oct 30 2012