digitalmars.D.learn - Linkage question
- frame (20/20) Jan 24 2022 If I declare a function as extern(C) inside a DLL, I have also to
- Stanislav Blinov (5/9) Jan 24 2022 The difference is in how arguments are being passed, which you
- frame (7/12) Jan 24 2022 Ah, yes. Thanks. Maybe I should read it more carefully =)
- Paul Backus (7/11) Jan 24 2022 Windows has two calling conventions for C functions, `cdecl` and
- duser (8/22) Jan 24 2022 that's a bug with dmd or the spec, arguments are currently passed
If I declare a function as extern(C) inside a DLL, I have also to cast the function pointer as extern(C) or it fails calling, eg. ```d // --- my.dll export extern (C) void log(int mode, string a, string b, string c) { /* stuff */ } // --- main.d alias T = extern (C) void function(int, string, string, string); auto fnPtr = cast(T)GetProcAddress(/* stuff */); ``` I understand that the linkage must match but besides the name mangling, what's happen here? What is the difference if I remove the `extern (C)` part from the T alias? Doing that supplies 2nd and 3rd paramter as fine pointers but the 1st argument comes wrong (eg. 10 becomes -218697648) and the last argument is garbage too, so the D-linkage format is something different. Would like to know where the linkage format is defined, thx.
Jan 24 2022
On Monday, 24 January 2022 at 17:23:01 UTC, frame wrote:I understand that the linkage must match but besides the name mangling, what's happen here? What is the difference if I remove the `extern (C)` part from the T alias?The difference is in how arguments are being passed, which you seem to have discovered already :)Would like to know where the linkage format is defined, thx.It should be here: https://dlang.org/spec/abi.html although IIRC it might not be 100% up to date.
Jan 24 2022
On Monday, 24 January 2022 at 18:30:02 UTC, Stanislav Blinov wrote:The difference is in how arguments are being passed, which you seem to have discovered already :)Ah, yes. Thanks. Maybe I should read it more carefully =) It claims that the D calling convention matches C. But it seems that the arguments are pushed in order whereas C does it in reverse order and the -218697648 value is indeed my 3rd string pointer.Would like to know where the linkage format is defined, thx.It should be here: https://dlang.org/spec/abi.html although IIRC it might not be 100% up to date.
Jan 24 2022
On Monday, 24 January 2022 at 19:41:30 UTC, frame wrote:It claims that the D calling convention matches C. But it seems that the arguments are pushed in order whereas C does it in reverse order and the -218697648 value is indeed my 3rd string pointer.Windows has two calling conventions for C functions, `cdecl` and `stdcall`. In D, `cdecl` is called `extern (C)` and `stdcall` is called `extern (Windows)`. Windows API functions use the `stdcall` convention [1], so you need to use `extern (Windows)` when calling them from D. [1] https://docs.microsoft.com/en-us/cpp/cpp/stdcall?view=msvc-170
Jan 24 2022
On Monday, 24 January 2022 at 19:41:30 UTC, frame wrote:On Monday, 24 January 2022 at 18:30:02 UTC, Stanislav Blinov wrote:that's a bug with dmd or the spec, arguments are currently passed in reverse order compared to C on 64-bit even though they should be the same see: https://issues.dlang.org/show_bug.cgi?id=20204 https://github.com/dlang/dmd/pull/13287 https://github.com/dlang/dlang.org/pull/3120The difference is in how arguments are being passed, which you seem to have discovered already :)Ah, yes. Thanks. Maybe I should read it more carefully =) It claims that the D calling convention matches C. But it seems that the arguments are pushed in order whereas C does it in reverse order and the -218697648 value is indeed my 3rd string pointer.Would like to know where the linkage format is defined, thx.It should be here: https://dlang.org/spec/abi.html although IIRC it might not be 100% up to date.
Jan 24 2022