Need help with Windows linkage ( DMD using ImportC)

Carl Sturtivant sturtivant at gmail.com
Sun Mar 10 23:29:57 UTC 2024


On Thursday, 7 March 2024 at 18:14:32 UTC, Gregor Mückl wrote:
> 2. C code referring to MSVC-specific compiler intrinsics. At 
> least InterlockedExchangeAdd, InterlockedExchangeAdd64 and 
> _stosb are such intrinsics. This is harder to resolve. There 
> are two ways forward here: either implement a shim function 
> that replicates the intrinsic's functionality if possible or 
> add support for these intrinsics to DMD.

Thanks for the explanation, on the strength of which I found a 
way to deal with this correctly.

I made `intrinsics1.c` that has `#include <intrin.h>` and 
contains an actual function for each missing intrinsic; e.g. for 
the missing __shiftright128 it has
```C
unsigned __int64 D__shiftright128(
    unsigned __int64 LowPart,
    unsigned __int64 HighPart,
    unsigned char Shift
)
{ return __shiftright128(LowPart, HighPart, Shift); }

```
where I got the prototypes from this [list of 
intrinsics](https://learn.microsoft.com/en-us/cpp/intrinsics/alphabetical-listing-of-intrinsic-functions?view=msvc-170).

Compiling this with MSVC `cl -c intrinsics1.c` produces a COFF 
object `intrinsics1.obj` containing an actual function to link to 
for each intrinsic. So this stage writes the code so we don't 
have to.

As a matter of necessity, the names of the functions in 
`intrinsics1.c` representing the MSVC intrinsics are not the same 
as their actual names. By my convention above they are prefixed 
with "D". Now we could simply write an extern(C) D function in a 
module say `vcintrinsics.d`, that has exactly the intrinsic's 
name, and calls the "D" prefixed function linked from 
`intrinsics1.obj`, e.g. for the above example `vcintrinsics.d` 
could contain
```D
extern(C):

extern ulong D__shiftright128(ulong LowPart, ulong HighPart, 
ubyte Shift);

ulong __shiftright128(ulong LowPart, ulong HighPart, ubyte Shift){
     return D__shiftright128(LowPart, HighPart, Shift);
}
```
As DMD doesn't know of these intrinsics, it won't complain about 
defining a function with exactly the same name as an intrinsic so 
as to implement that intrinsic as an actual function, solving the 
problem. `dmd -lib vcintrinsics.d intrinsics1.obj` then produces 
a library that resolves the linkage issue.

An alternative not involving having two function calls to 
implement an intrinsic is to compile `intrinsics1.c` with MSVC 
into a DLL, and using a DEF file that renames the exports just 
like part of the solution 
[here](https://forum.dlang.org/post/ruupyklfkrvnjtkerhmx@forum.dlang.org) make those functions available under their original names when linking to its import library.

A lot of both of the above is boilerplate and can be automated. 
It would be even nicer if the MSVC tools could be persuaded to 
proceed in a similar way with DEF file renaming when building a 
static library, but I have not succeeded in making this happen. 
Anyone?


More information about the Digitalmars-d-learn mailing list