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)?
  cfunc(&dcallback);

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.

Denis

Reply via email to