Jump to page: 1 2
Thread overview
ImportC: Windows.h
Nov 30
name
Nov 30
Kagamin
Nov 30
name
Nov 30
name
Dec 01
Kagamin
Dec 01
name
Dec 01
name
Dec 01
Kagamin
Dec 01
name
Dec 02
name
Dec 02
name
November 30

Does anyone know of a workaround? (I'm using DMD 2.105.3.)

main.d:

import wintest;

pragma(lib, "user32");

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

wintest.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
Issue 20020 - Compiler should offer atomic intrinsics

November 30

You can declare them

extern(C) void _InterlockedExchangeAdd(){ assert(false); }
November 30

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.

November 30

Weird... building with dmd -m64 -i main.d works fine.

Then, I tried calling CreateFileW, passing GENERIC_READ for [in] dwDesiredAccess; I get this:

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

ImportC seems very brittle. :/

December 01

Is GENERIC_WRITE awailable?

December 01

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:

// 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:

	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...

December 01

So, uh, I tried deleting the parens off GENERIC_READ's value:

winnt.h:

//
//  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?

December 01

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.

December 01

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` ?

December 02

Minimum thing to reproduce bug:

main.d:

import test;

void main() {
  auto a = FILE_MAP_READ;
}

test.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):

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;
        // ...
}
« First   ‹ Prev
1 2