On Friday, 26 June 2020 at 08:15:27 UTC, Jacob Carlborg wrote:
On Friday, 26 June 2020 at 00:30:22 UTC, Denis wrote:

  extern(C) void cfunc(void function(int));
  extern(C) void dcallback(int x) {...}         <-- Why extern(C)?

Can this be rewritten, dropping the prefix from the second line? If not, it would be helpful to know why "extern(C)" is needed here too.

No, it cannot be dropped. `extern(C)` is required because C and D are using different calling conventions (D functions are also mangled). For example, D (at least DMD and LDC) are passing the arguments to the function in reverse.

OK, now this makes sense.

I tested calling the same callback function directly from D: it compiled and worked correctly. So at least prefixing the callback function with `extern(C)` doesn't prevent the rest of the D program from calling it too.

(2) Is there a way to restrict the invocation of a linked C function to one specific D function?


For functions nested in a D language construct (class, struct, function) the compiler will always use the D mangling, instead of the C mangling. In theory it would be possible to workaround that by forcing the mangled name using `pragma(mangle)`, but for some reason the compiler doesn't allow `pragma(mangle)` inside a function body, on a nested function declaration.

You can wrap up everything in a struct, as follows:

I see.

Thank you very much for these explanations and code -- the insights are very helpful.


Reply via email to