www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - ImportC: Windows.h

reply name <n m.e> writes:
Does anyone know of a workaround? (I'm using DMD 2.105.3.)

main.d:
```d
import wintest;

pragma(lib, "user32");

void main() {
     MessageBoxA(null, cast(char*)"", cast(char*)"", MB_OK);
}
```

wintest.c:
```c
#include <Windows.h>
```

```
D:\dmd.2.105.3.windows>"D:\dmd.2.105.3.windows\dmd2\windows\bin64\dmd.exe" -m64
main.d wintest.c
main.obj : error LNK2019: unresolved external symbol 
_InterlockedExchangeAdd referenced in function 
_InlineInterlockedAdd
main.obj : error LNK2019: unresolved external symbol 
_InterlockedExchangeAdd64 referenced in function 
_InlineInterlockedAdd64
main.obj : error LNK2019: unresolved external symbol _mul128 
referenced in function MultiplyExtract128
main.obj : error LNK2019: unresolved external symbol 
__shiftright128 referenced in function MultiplyExtract128
main.obj : error LNK2019: unresolved external symbol _umul128 
referenced in function UnsignedMultiplyExtract128
main.obj : error LNK2019: unresolved external symbol __stosb 
referenced in function RtlSecureZeroMemory
main.obj : error LNK2019: unresolved external symbol 
__readgsqword referenced in function NtCurrentTeb
main.obj : error LNK2019: unresolved external symbol 
__imp_MapViewOfFileNuma2 referenced in function MapViewOfFile2
main.exe : fatal error LNK1120: 8 unresolved externals
Error: linker exited with status 1120
```

**Related:**
[Issue 23894 - ImportC: _InterlockedExchangeAdd and a ton of 
other VC intrinsics are not 
recognized](https://issues.dlang.org/show_bug.cgi?id=23894)
[Issue 20020 - Compiler should offer atomic 
intrinsics](https://issues.dlang.org/show_bug.cgi?id=20020)
Nov 30 2023
parent reply Kagamin <spam here.lot> writes:
You can declare them
```
extern(C) void _InterlockedExchangeAdd(){ assert(false); }
```
Nov 30 2023
parent reply name <n m.e> writes:
On Thursday, 30 November 2023 at 08:54:40 UTC, Kagamin wrote:
 You can declare them
 ```
 extern(C) void _InterlockedExchangeAdd(){ assert(false); }
 ```
That works, thanks.
Nov 30 2023
parent reply name <n m.e> writes:
Weird... building with ```dmd -m64 -i main.d``` works fine.

Then, I tried calling 
[CreateFileW](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-f
leapi-createfilew), passing ```GENERIC_READ``` for ```[in] dwDesiredAccess```;
I get this:

```main.d(7): Error: undefined identifier GENERIC_READ```.


ImportC seems very brittle. :/
Nov 30 2023
parent reply Kagamin <spam here.lot> writes:
Is GENERIC_WRITE awailable?
Dec 01 2023
next sibling parent name <n m.e> writes:
On Friday, 1 December 2023 at 08:45:30 UTC, Kagamin wrote:
 Is GENERIC_WRITE awailable?
No, it's not. I tried building with LDC 1.35.0: ```"D:\ldc2-1.35.0-windows-x64\bin\ldc2.exe" main.d -i -vcg-ast```. winnt.h: ```c // begin_wdm // begin_ntoshvp typedef DWORD ACCESS_MASK; typedef ACCESS_MASK *PACCESS_MASK; // end_ntoshvp // begin_access //////////////////////////////////////////////////////////////////////// // // // ACCESS TYPES // // // //////////////////////////////////////////////////////////////////////// // begin_wdm // // The following are masks for the predefined standard access types // #define DELETE (0x00010000L) #define READ_CONTROL (0x00020000L) #define WRITE_DAC (0x00040000L) #define WRITE_OWNER (0x00080000L) #define SYNCHRONIZE (0x00100000L) #define STANDARD_RIGHTS_REQUIRED (0x000F0000L) #define STANDARD_RIGHTS_READ (READ_CONTROL) #define STANDARD_RIGHTS_WRITE (READ_CONTROL) #define STANDARD_RIGHTS_EXECUTE (READ_CONTROL) #define STANDARD_RIGHTS_ALL (0x001F0000L) #define SPECIFIC_RIGHTS_ALL (0x0000FFFFL) // // AccessSystemAcl access type // #define ACCESS_SYSTEM_SECURITY (0x01000000L) // // MaximumAllowed access type // #define MAXIMUM_ALLOWED (0x02000000L) // // These are the generic rights. // #define GENERIC_READ (0x80000000L) #define GENERIC_WRITE (0x40000000L) #define GENERIC_EXECUTE (0x20000000L) #define GENERIC_ALL (0x10000000L) // // Define the generic mapping array. This is used to denote the // mapping of each generic access right to a specific access mask. // typedef struct _GENERIC_MAPPING { ACCESS_MASK GenericRead; ACCESS_MASK GenericWrite; ACCESS_MASK GenericExecute; ACCESS_MASK GenericAll; } GENERIC_MAPPING; typedef GENERIC_MAPPING *PGENERIC_MAPPING; ``` wintest.c.cg: ```d alias ACCESS_MASK = uint; alias PACCESS_MASK = uint*; align struct _GENERIC_MAPPING { uint GenericRead = void; uint GenericWrite = void; uint GenericExecute = void; uint GenericAll = void; } alias GENERIC_MAPPING = _GENERIC_MAPPING; alias PGENERIC_MAPPING = _GENERIC_MAPPING*; ``` It ended up not producing any enums inbetween...
Dec 01 2023
prev sibling parent reply name <n m.e> writes:
So, uh, I tried deleting the parens off GENERIC_READ's value:

winnt.h:
```c
//
//  These are the generic rights.
//

#define GENERIC_READ                     0x80000000L
#define GENERIC_WRITE                    (0x40000000L)
#define GENERIC_EXECUTE                  (0x20000000L)
#define GENERIC_ALL                      (0x10000000L)
```

And... that's what works. Uhh, why?
Dec 01 2023
parent reply Kagamin <spam here.lot> writes:
In C macros can be defined to any expression, so ImportC 
interprets these parentheses as arbitrary expression macros and 
skips them thinking they are helper macros that can't be always 
translated.
Dec 01 2023
parent reply name <n m.e> writes:
On Friday, 1 December 2023 at 10:23:08 UTC, Kagamin wrote:
 In C macros can be defined to any expression, so ImportC 
 interprets these parentheses as arbitrary expression macros and 
 skips them thinking they are helper macros that can't be always 
 translated.
But does that explain why using ```FILE_MAP_READ``` (in "memoryapi.h") also produces ```Error: undefined identifier `FILE_MAP_READ` ```?
Dec 01 2023
parent reply name <n m.e> writes:
Minimum thing to reproduce bug:

main.d:
```d
import test;

void main() {
   auto a = FILE_MAP_READ;
}
```

test.c
```c
#define SECTION_MAP_READ  0x0004
#define FILE_MAP_READ     SECTION_MAP_READ
```

build with ```"D:\dmd.2.105.3.windows\dmd2\windows\bin64\dmd.exe" 
-c test.c -vcg-ast```.

test.c.cg (```FILE_MAP_READ``` doesn't show up):
```d
extern (C)
{
	enum int __IMPORTC__ = 1;
	enum int _M_X64 = 100;
	enum int _MSC_EXTENSIONS = 1;
	enum int _MSC_BUILD = 0;
	enum int _WIN64 = 1;
         // ...
	enum int SECTION_MAP_READ = 4;
         // ...
}
```
Dec 01 2023
parent reply Stefan Koch <uplink.coder googlemail.com> writes:
On Saturday, 2 December 2023 at 05:16:43 UTC, name wrote:
 Minimum thing to reproduce bug:

 main.d:
 ```d
 import test;

 void main() {
   auto a = FILE_MAP_READ;
 }
 ```

 test.c
 ```c
 #define SECTION_MAP_READ  0x0004
 #define FILE_MAP_READ     SECTION_MAP_READ
 ```

 build with 
 ```"D:\dmd.2.105.3.windows\dmd2\windows\bin64\dmd.exe" -c 
 test.c -vcg-ast```.

 test.c.cg (```FILE_MAP_READ``` doesn't show up):
 ```d
 extern (C)
 {
 	enum int __IMPORTC__ = 1;
 	enum int _M_X64 = 100;
 	enum int _MSC_EXTENSIONS = 1;
 	enum int _MSC_BUILD = 0;
 	enum int _WIN64 = 1;
         // ...
 	enum int SECTION_MAP_READ = 4;
         // ...
 }
 ```
It doesn't show up since it's defined as an Identifier Expression which cannot be resolved.
Dec 02 2023
parent name <n m.e> writes:
On Saturday, 2 December 2023 at 08:36:01 UTC, Stefan Koch wrote:
 On Saturday, 2 December 2023 at 05:16:43 UTC, name wrote:
 Minimum thing to reproduce bug:
 [...]
It doesn't show up since it's defined as an Identifier Expression which cannot be resolved.
But why can't it be resolved?
Dec 02 2023