0

My error is: hello_world.obj : error LNK2019: unresolved external symbol _MessageBeep referenced in function _main@0

Now I am aware there are a ton of questions on this topic. I have looked at them and I still can't quite figure it out. Needless to say, I am a noob that is compiling this example code just to better understand computer technology.

I am using MSVC build developer tools for this. That is, with the developer command prompt for VS2019 (x86 native tools, although I am on a 64 bit machine, I don't think that would be an issue). I am compiling the code with MASM and linking with LINK.

The source code:

.686P
.model FLAT, stdcall
includelib User32.Lib
PUBLIC main
EXTRN MessageBeep:PROC

_TEXT SEGMENT
main PROC
push 0FFFFFFFFh
call MessageBeep
xor  eax,eax
ret
main ENDP
_TEXT ENDS
END 

First I compile the source file with:

ml /c hello_world.asm

Then I link with:

LINK /ENTRY:main hello_world.obj user32.lib

(I know specifying user32.lib here is redundant because of the includelib in the source file, but I do it for my sanity to make sure that I am indeed linking with the user32 library)

I believe I am linking with the appropriate library, as I have checked the symbol tale for user32.lib and it does contain the _MessageBeep symbol. (I wanted to make sure it wasn't an inline function or something like that)

...
_MapVirtualKeyW@8
_MapWindowPoints@16
_MenuItemFromPoint@16
_MessageBeep@4
_MessageBoxA@16
_MessageBoxExA@20
_MessageBoxExW@20
...

Since I am using the VS2019 developer command prompt, when looking at the %LIB% enviorment variable I do have a path that points to the folder containing the x86 version of User32.Lib.

C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\um\x86

Is one of the paths that shows when I do echo %lib%

What am I doing wrong here?

Horace
  • 131
  • 5
  • 2
    You need to use the `@4` suffix as well. – Jester Sep 13 '21 at 13:58
  • Thanks! That worked, if you will, could you post this as an answer so I can credit you. Also, is this @4 suffix hinting at the size of the inputs or something? Is there a history behind that? – Horace Sep 13 '21 at 14:05
  • 1
    You are correct, it's the size of arguments. As the callee removes the arguments from the stack it's important that it agrees with the caller, hence the encoding of the number of bytes into the symbol. – Jester Sep 13 '21 at 17:56
  • 1
    [Win32 Assembly - Extern function naming (The meaning of '@')](https://stackoverflow.com/q/40030484) explains the history and purpose. Link errors are better than run-time stack corruption if caller and callee don't agree about the size of args for a C function. – Peter Cordes Sep 14 '21 at 03:05

0 Answers0