Difference in linker-generated name (C++/C) ($$FYZAXXZ - $$J0YAXXZ) - c++

I am having trouble linking my project. I get this error message:
error LNK2019: unresolved external symbol "void __cdecl TimerInit(void)" (?TimerInit##$$FYAXXZ)
The function TimerInit is in a different .CPP file in the same project. When I use DUMPBIN to look at the contents of the corresponding .OBJ file, I see that the compiler generated this symbol:
?TimerInit##$$J0YAXXZ
I can't figure out why that is - 'J0' instead of 'F'. Must be something with calling conventions.
This is with Visual Studio 2008, if that makes a difference.

Using the undname command line tool, we can see that the symbol in the .obj is
Undecoration of :- "?TimerInit##$$J0YAXXZ"
is :- "extern "C" void __cdecl TimerInit(void)"
while the one the linker is looking for is not extern "C".
I don't have access to VS 2008 to check this, but it appears that wherever you define the TimerInit function, it is in an extern "C" declaration of some kind. Newer versions of Visual Studio do not export mangled extern "C" names (TimerInit would be _TimerInit or just TimerInit, depending on the compiler version), and I am unsure what your declarations look like to produce this since you do not show them in the question.
Either remove the extern "C" in the definition of TimerInit, or consider upgrading to a more recent version of Visual Studio.

Related

c++ visual studio, unresolved external symbol using .lib file [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 5 years ago.
I have inherited a legacy project which utilizes some external functions from a *.lib. From what I was told, the syntax for using the *.lib was correct and this
was buildable in whatever visual studio version they used. (ie, there is an extern "C" prototype file, and all the function signatures are correct).
When building, I get "error LNK2019: unresolved external symbol _A86_ReadConfigReg#12 referenced in function ..."
I'm pretty confident that this is related to the *.lib file since the *.lib file has "A86" in the name...There is also a *.dll with the same name.
I went to project properties -> Linker -> Input and listed the *.lib file name in "Additional Dependencies", but no luck. I tried adding the include directories, copying the *.lib & *.dll to the executable location. But no luck.
How do I go about fixing this error?
First thing you should do is inspect the library to make sure the referenced function is there. Start an msvc developer command prompt, and run dumpbin.exe
Syntax:
dumpbin /exports <full path library name>
This will give you a listing of all exported symbols from the library.
You'll get a clearer idea of what to do from there.
[EDIT]
dumpbin told you that your lib exports a function called A86_ReadConfigReg, which is a __cdecl signature and not a __stdcall signature like _A86_ReadConfigReg#12 that your linker expects.... At least two things you should do/check in order of priority.
Your linker is looking for a pascal call signature and this is very odd. Does your project have __stdcall as a default for function calls? That's controlled by the /Gz switch in Project Properties->C/C++->Advanced->Calling Convention. Default should be set to __cdecl (/Gd)
You should check that your include files enclose all the function declarations in an extern "C" { } block. If they don't, you can place the block around the #include directive, so you do not have to modify the library's files.
Like so:
extern "C" {
#include <mylib.h>
}

MSVC name mangling

I am trying to build Lua and QtLua with MSVC 2015 x86 and I have encountered an issue with exported/imported symbols.
Here is what I do forbuilding Lua 5.3.2 (source):
cl /MD /O2 /c /DLUA_BUILD_AS_DLL *.c
ren lua.obj lua.o
ren luac.obj luac.o
link /DLL /IMPLIB:lua5.3.2.lib /OUT:lua5.3.2.dll *.obj
link /OUT:lua.exe lua.o lua5.3.2.lib
lib /OUT:lua5.3.2-static.lib *.obj
link /OUT:luac.exe luac.o lua5.3.2-static.lib
So far it works and dependancy walker shows that functions are exported without any mangling.
Then I build QtLua using cmake and I'v got about 100 errors like:
error LNK2019: unresolved external symbol _lua_close referenced in function "public: virtual __thiscall QtLua::State::~State(void)" (??1State#QtLua##UAE#XZ)
So basically my issue is that the DLL exports lua_close and the linker looks for _lua_close.
After a bit of searching the _lua_close format seems legit as Microsoft documentation states that C symbols called with __cdecl are mangled with a '_' prefix.
However I don't get why the DLL exports unmangled names.
Function declaration when compiled in Lua (C files)
__declspec(dllexport) void (lua_close) (lua_State *L);
Function declaration when compiled in QtLua (C++ files)
extern "C" {
extern void (lua_close) (lua_State *L);
}
Quick answer
MSVC did not found the lua DLL (or lib).
Long answer
Exported C functions called using __cdecl are not mangled, whereas internal C functions called using __cdecl are mangled with a '_' prefix.
Source: http://wyw.dcweb.cn/stdcall.htm
To fix my issue I took all source files from QtLua and created a qmake project from them. And tadaa! It works! (Well, it doesn't because QtLua doesn't seem to be tested on anything else than gcc, but I got rid of this linker problem).
My conclusion is that:
MSVC complains about not finding _function and is in fact looking for function (or maybe both).
CMake, even if it found the lua library at config time, failed to pass the proper options to the linker at build time.

error LNK2019 unresolved external symbol when trying to link dll

I know many people have asked about this error and trust me I've read ALL of them and followed all the steps! But I'm still getting the unresolved external symbol error.
I'm trying to use the dll of lp_solve (a linear programming package) in my c++ code in visual studio 2012.
The error message I'm getting is:
Error 80 error LNK2019: unresolved external symbol _make_lp#8 referenced in function "void __cdecl my_solve(BLAH BLAH)
The function make_lp() is from the lp_solve package and I'm calling it from my_solve() in my code. This error message pops up for each solver function I call. Seems the linker just couldn't find any of the implementation of these functions.
I've done the following
put #include "lp_lib.h" in my source code
put the .dll, .h and .lib files from the lp_solve package in the working directory and
added the path under Linker:General:Additional Library Directories.
added the lib under Linker:Input:Additional dependency
What's wrong?
Thanks for your help!
The problem I had was solved after realizing I downloaded the WIN64 package for lp_solve but my visual studio is using WIN32 as build platform (even though my machine is x86_64).
Using extern "C" may be helpful while including lp_lib.h in your .cpp as follows:
extern "C"
{
#include "lp_lib.h"
}
For more information, please check this link:
http://www.geeksforgeeks.org/extern-c-in-c/

C++: Unresolved external symbol _sprintf and _sscanf in Visual Studio 2015

For a research project, I'm writing a C++ add-on to a scientific computing language. Unfortunately the library that allows users to do this is not kept very well up-to-date.
I started the project in XCode, where it built fine. Later I had to move to a PC, so I migrated the code to Visual Studio 2015. Since doing this, I haven't been able to build due to the following errors:
LNK2001 : unresolved external symbol _sprintf
LNK2019 : unresolved external symbol _sscanf referenced in function _GetDDouble
LNK2019 : unresolved external symbol _sprintf referenced in function _CheckRunningInMainThread
An attempted fix was to add the header #define _CRT_SECURE_NO_WARNINGS. However, this a) fixed no errors and b) added the warning C4005 : '_CRT_SECURE_NO_WARNINGS': macro redefinition. I assume the library already defined this macro, anticipating this problem. Regardless, it didn't solve the problem.
How should I proceed?
Add the following library to the linker input files:
legacy_stdio_definitions.lib
VS 2015 now uses inline definitions that call internal functions for many of the stdio.h functions. If an object file (or library member) depends on one of those functions, then the legacy_stdio_definitions.lib provides an externally linkable version of the function that can be linked to.
Your other option is to recompile the unit that depends on those functions with VS 2015 (this is probably the preferred option).
I got this error compiling cycling max plugins against version 5 max sdk (pure c api). The legacy library fix didn't work for me (it should have, and if anyone had any idea why it mightn't I'd be curious), but I defined _NO_CRT_STDIO_INLINE before stdio was loaded and that did do the trick.
I recently encountered this and was able to add User32.lib to Linker > Input > Additional Dependencies.
You could also include #pragma comment (lib, "User32.lib") in your code.

DLL and Name Mangling

I have a third-party LIB which has symbols exported as plain C/cdecl, so for example dumpbin.exe /SYMBOLS reports that both __imp_nvmlInit and nvmlInit are exported.
However in Visual Studio 2010 when I try to import them, the header file will have
extern "C" nvmlReturn_t nvmlInit(...);
but when I try to compile, I get the following error:
main.obj : error LNK2019: unresolved external symbol _nvmlInit referenced in function _main
How can I stop Visual Studio from looking for that symbol with a leading underscore? __declspect(dllimport) doesn't work because then it decorates to __imp__nvmlInit (one underscore too many).
Thanks.
That is a linker error. You need to link with the .LIB file associated with DLL, which will give the linker a promise that the function will be available at run-time when the DLL itself is loaded.