Re: Need help with Windows linkage ( DMD using ImportC)

2024-03-10 Thread Carl Sturtivant via Digitalmars-d-learn

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 ` 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/ruupyklfkrvnjtker...@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?


Re: Can a D library have some types determined by the client program?

2024-03-10 Thread Liam McGillivray via Digitalmars-d-learn

On Sunday, 10 March 2024 at 04:39:33 UTC, Liam McGillivray wrote:

https://github.com/LiamM32/Open_Emblem/tree/templates-interfaces

I will probably merge it into master soon.


I have put up a merge request for these changes I have made to 
the library and the Raylib front-end. I would be interested in 
having my code looked at by someone more experienced than me 
(which would be everyone who has replied here and most of those 
reading).

https://github.com/LiamM32/Open_Emblem/pull/2

You can take a look in `source/map.d` where the former `Map` 
class has been replaced with the `Map` interface and the 
`MapTemp` template. You may also look in 
`oe-raylib/source/mission.d`, and compare how sprites were 
handled before vs after.


Of course, you can also compile and run it yourself (assuming I 
didn't accidentally leave out a file).


Other commentary on my code would also be appreciated.

I don't know if there's a forum section appropriate for sharing 
personal projects, but I may post there too.


Re: Can a D library have some types determined by the client program?

2024-03-10 Thread cc via Digitalmars-d-learn

On Saturday, 9 March 2024 at 22:03:34 UTC, Liam McGillivray wrote:
Secondly, I found out that interfaces can't have variables. 
What!? That's crazy! Why wouldn't they? They totally should. 
Doesn't this mean that I will need to use getter and setter 
functions instead of direct access when using interfaces? I 
don't like this.


An interface just defines an interface, a set of method 
signatures that a class can respond to, and must implement.  If 
you want storage and functionality, you can define a base class.  
A derived class can inherit from either one base class or one or 
more interfaces.  Or a combination, but multiple inheritance is 
not a well-liked idea.


```d
class Map {
int someVar = 3;
void someFunc() {
// default behavior
writeln("hello");
}
}

class CustomMap!TierType : Map {
override void someFunc() {
// new behavior
writefln("good day %s %s", someVar, TierType.stringof);
}
}

void main() {
auto map = new Map;
map.someFunc() // hello
map = new CustomMap!uint;
map.someFunc() // good day 3 uint
}
```

In the last line of this code, the variable `map` is still of 
type `Map` (chosen by `auto` when it received `new Map`, but the 
actual class object it references is of type `CustomMap!uint`, 
hence calling a virtual function like `someFunc` calls the 
derived version instead of the original.  Note that functions 
that take template arguments (not included here) don't 
necessarily follow this behavior; mixing templated methods and 
inheritance has some pitfalls.