NO

Author Topic: Linker Error *SOLVED*  (Read 4326 times)

Offline Mikael

  • Member
  • *
  • Posts: 7
Linker Error *SOLVED*
« on: April 28, 2022, 03:40:15 PM »
This compiles cleanly as it should:


#define WIN32_DEFAULT_LIBS
#include <Windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    VirtualAlloc(
        NULL,         // BaseAddress
        65536,        // Size
        MEM_COMMIT,   // AllocationType
        PAGE_NOCACHE  // PageProtection
    );
    return 0;
}


But this fails with POLINK: error: Unresolved external symbol 'VirtualAlloc2':


#define WIN32_DEFAULT_LIBS
#include <Windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    VirtualAlloc2(
        NULL,         // Process
        NULL,         // BaseAddress
        65536,        // Size
        MEM_COMMIT,   // AllocationType
        PAGE_NOCACHE, // PageProtection
        NULL,         //*ExtendedParameters
        NULL          // ParameterCount
    );
    return 0;
}


Both functions are located in kernel32.lib and should be found by including Windows.h so I don't think I'm doing anything wrong here.



« Last Edit: April 29, 2022, 05:01:06 PM by Mikael »

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2113
Re: Linker Error (I'm fairly sure this isn't my fault!)
« Reply #1 on: April 28, 2022, 04:04:19 PM »
Sorry, but "VirtualAlloc2()" is from SDK WIN10, and is not available yet in actual PellesC libraries.
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

Offline Mikael

  • Member
  • *
  • Posts: 7
Re: Linker Error (I'm fairly sure this isn't my fault!)
« Reply #2 on: April 28, 2022, 04:18:08 PM »
Oh.  :(

Any idea when it may happen? I'm just starting on a major project, and VirtualAlloc2 is *required* for the foundational layer. Do I have to use Microsoft's compiler? I'd rather not, because I just feel so much more at home with Pelles!

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2122
Re: Linker Error (I'm fairly sure this isn't my fault!)
« Reply #3 on: April 28, 2022, 04:39:51 PM »
You create your own library for it like this:
Code: [Select]
polib.exe -def:kernelx.def -out:kernelx.libkernelx.def
Code: [Select]
LIBRARY kernel32.dll
EXPORTS
VirtualAlloc2
May the source be with you

Offline Mikael

  • Member
  • *
  • Posts: 7
Re: Linker Error (I'm fairly sure this isn't my fault!)
« Reply #4 on: April 28, 2022, 05:11:38 PM »
Thanks TimoVJL, that almost solved the problem!  8)

I created a kernelx.lib as instructed and now the program compiles just fine.

However, when I run it I get a popup saying:

"The procedure entry point VirtualAlloc2 could not be located in the dynamic link library C:\ ... test.exe"

Any idea what I'm missing here?

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
Re: Linker Error (I'm fairly sure this isn't my fault!)
« Reply #5 on: April 28, 2022, 05:58:51 PM »
Apparently VirtualAlloc2() is in kernelbase.dll, not kernel32.dll (for unknown reasons)...
/Pelle

Offline Mikael

  • Member
  • *
  • Posts: 7
Re: Linker Error *SOLVED*
« Reply #6 on: April 28, 2022, 06:22:30 PM »
Ah, Microsoft played a little joke on us, saying a function is in one dll, then hiding it in another! :P

Anyway, I'm now free to play with all the fancy WIN10 stuff!

Thanks Timo and Pelle for the help, and for teaching me how to fix similar problems myself in the future.

Offline Mikael

  • Member
  • *
  • Posts: 7
Re: Linker Error *SOLVED*
« Reply #7 on: April 29, 2022, 12:40:37 PM »
OK, it seems I spoke too soon...

I can now get VirtualAlloc2() to compile by adding a special .lib as instructed, but the compiler still can't find its prototype from Windows.h

I tried to work around this by writing the prototype myself, and that made it compile cleanly, but no matter what I feed the function it always returns 87 (ERROR_INVALID_PARAMETER). The problem is most likely that the Windows headers are a rat's nest of macros, so trying to work around having the correct header version is a fool's errand.

It seems to be too messy to try and use Pelles C for Windows 10 development, since it doesn't support the WIN10 SDK out of the box.

I suggest being more explicit about that - I didn't find this information anywhere, so I just assumed a compiler that supports up-to-date C on Windows would also support up-to-date Windows. Never assume anything, I guess!

It's a real pity since I love the clean simplicity of Pelles C as a development environment, but I can't afford to waste more time on this, so I'll be using MSVC instead.

Thanks for your time.

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
Re: Linker Error
« Reply #8 on: April 29, 2022, 02:00:26 PM »
If I change
Code: [Select]
PAGE_NOCACHEto
Code: [Select]
PAGE_NOCACHE | PAGE_READWRITEit seems to work here...
/Pelle

Offline Mikael

  • Member
  • *
  • Posts: 7
Re: Linker Error
« Reply #9 on: April 29, 2022, 05:00:45 PM »
OK, that actually worked! I thought I had failed to write correct prototypes to "augment" what's missing in the pre-WIN10 Windows.h, but that wasn't the problem.

To recap what I learned here:

The WIN10 SDK isn't supported out of the box, but the missing functions can still be used by doing the following:

1. Use polib to create a .lib with the missing functions.

2. Hack any needed prototypes into the code. For this example I did this:

---------------------------------------------------------------------------------------
#ifdef __POCC__
  #define WIN32_DEFAULT_LIBS
#endif
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#ifdef __POCC__
  #define WIN32_DEFAULT_LIBS
  typedef struct MEM_EXTENDED_PARAMETER {
    struct {
      DWORD64 Type;
      DWORD64 Reserved;
    } DUMMYSTRUCTNAME;
    union {
      DWORD64 ULong64;
      PVOID   Pointer;
      SIZE_T  Size;
      HANDLE  Handle;
      DWORD   ULong;
    } DUMMYUNIONNAME;
  } MEM_EXTENDED_PARAMETER, *PMEM_EXTENDED_PARAMETER;

  PVOID VirtualAlloc2(
    HANDLE                  Process,
    PVOID                   BaseAddress,
    SIZE_T                  Size,
    ULONG                   AllocationType,
    ULONG                   PageProtection,
    MEM_EXTENDED_PARAMETER *ExtendedParameters,
    ULONG                   ParameterCount
  );
#endif

---------------------------------------------------------------------------------------

So I'm back to using Pelles after all!

It's a bit of a pain to work around the missing functionality TBH, but at least I get to develop in a sensible IDE. I'll still need to make it compile on other compilers when it's done, but I won't have to do the entire development in a slow and bloated IDE that I hate...
8)

Sorry for taking up so much time, but I seriously wouldn't have sorted this out without help.

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
Re: Linker Error *SOLVED*
« Reply #10 on: April 29, 2022, 06:13:03 PM »
It has pretty much always been the case that the header and library files include with Pelles C are enough for me, and the not too demanding average user. If you want the latest and greatest definitions, you will have to go to the source (i.e. Microsoft). AFAIK, the "official" header and library files should work, probably with some (more or less) harmless warnings (that can be disabled)...

Keeping the Windows header and library files completely up-to-date is a big, boring, and thankless task - for which I'm payed very little. I doubt this will ever change much...
/Pelle

Offline Mikael

  • Member
  • *
  • Posts: 7
Re: Linker Error *SOLVED*
« Reply #11 on: April 30, 2022, 10:56:33 PM »
Yeah, I can understand it's a thankless task to keep adding support for an endless stream of new stuff no-one cares about. Sorry if I sounded negative, I was just tearing my hair out for a while...

I couldn't care less about the vast majority of stuff Microsoft adds either, but once in a while they do come up with something useful.

VirtualAlloc2 gives us the power to do some nifty things, like growing an array without moving any data around, just tell the OS to remap virtual memory. Calling the OS is pretty slow to begin with, but it can still be a win for big arrays.

Thanks again for the help!
 ;D