www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Callbacks and interfacing with C

reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
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
parent reply =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <alex lycus.org> writes:
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
parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
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:
 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
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.)
Oct 30 2012
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
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
prev sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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
parent Jacob Carlborg <doob me.com> writes:
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