Call Assembly procedure from C++ code using Visual Studio - c++

Got stuck with Visual Studio, Assembly and C++
C++:
extern "C" void asm_calculate_reals();
int main()
{
asm_calculate_reals();
return 0;
}
Assembly:
PUBLIC _asm_calculate_reals
.386
.model flat, stdcall
option casemap :none
.stack 100h
.code
_asm_calculate_reals PROC
;code goes here
ret
_asm_calculate_reals ENDP
end
When I build my project, Visual Studio reports the following error:
error LNK1120 error lnk1120 1 unresolved externals
I actually can't understand what's wrong with this easy part of program.
Log file:
Build started 16.04.2015 16:53:21.
1>Project "somepath\Reals loop 3variants.vcxproj" in node 2 (targets Build).
1>Link:
somepath\link.exe /ERRORREPORT:PROMPT /OUT:"somepath\Debug\Reals loop 3variants.exe" /INCREMENTAL /NOLOGO somelibs /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"somepath\Debug\Reals loop 3variants.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"somepath\Debug\Reals loop 3variants.lib" /MACHINE:X86 /SAFESEH:NO Debug\main.obj
Debug\reals.obj
1>main.obj : error LNK2019: reference to the unresolved external symbol _asm_calculate_reals in function _main
1>somepath\Debug\Reals loop 3variants.exe : fatal error LNK1120: unresolved identifiers: 1
1>Building project "somepath\Reals loop 3variants.vcxproj" finished (targets Build) with errors.
Build failed.

The actual problem was in the model definition inside assembly source.
.model flat, stdcall - was when the error appears.
.model flat, c - changing to this, works as expected.

Try to add this line to assembly code - global _asm_calculate_reals - To make it visible to linker. The "global" keyword in assembly tells the assembler to make the label visible from outside the file.

Related

Visual Studio link error "CloseWindow already defined" only when raylib.lib is linked after user32.lib

I have a compiled static library of raylib : raylib.lib. I compiled this library myself with Librarian > General > Additional Dependencies: winmm.lib
This library has a C function like the following:
void CloseWindow(void);
And I also have my very basic C++ project that uses raylib:
// main.cpp
#include "raylib.h"
int main()
{
InitWindow(100, 100, "");
while (!WindowShouldClose())
{
BeginDrawing();
ClearBackground(RAYWHITE);
EndDrawing();
}
CloseWindow();
return 0;
}
Now, when I compile my project with Linker > Additional Dependencies set to:
raylib.lib; user32.lib; shell32.lib; gdi32.lib
It compiles and links without any warning.
But when I swap the order of raylib.lib and user32.lib:
user32.lib; raylib.lib; shell32.lib; gdi32.lib
Then I get a linker error:
Link:
D:\Visual Studio Community 2019\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\link.exe
/ERRORREPORT:QUEUE /OUT:"bin\MyProject.exe" /INCREMENTAL:NO /NOLOGO /LIBPATH:bin
user32.lib raylib.lib shell32.lib gdi32.lib winmm.lib /MANIFEST
/MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG:FULL
/PDB:"bin\MyProject.pdb" /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE
/NXCOMPAT /IMPLIB:"bin\MyProject.lib" /MACHINE:X64 obj\Release\MyProject\main.obj
raylib.lib(core.obj) : error LNK2005: CloseWindow already defined in user32.lib(USER32.dll) [D:\example\MyProject.vcxproj]
bin\MyProject.exe : fatal error LNK1169: one or more multiply defined symbols found [D:\example\MyProject.vcxproj]
So how is this possible that it's already defined? Why does the linking order matter?
UPDATE
When I compiled raylib with Librarian > General > Additional Dependencies: winmm.lib; user32.lib then I get this warning (when compiling the library):
Lib:
D:\Visual Studio Community 2019\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\Lib.exe /OUT:"bin\raylib.lib" winmm.lib user32.lib /NOLOGO /MACHINE:X64 obj\Release\raylib\core.obj
obj\Release\raylib\models.obj
obj\Release\raylib\raudio.obj
obj\Release\raylib\rglfw.obj
obj\Release\raylib\shapes.obj
obj\Release\raylib\text.obj
obj\Release\raylib\textures.obj
obj\Release\raylib\utils.obj
user32.lib(USER32.dll) : warning LNK4006: __NULL_IMPORT_DESCRIPTOR already defined in winmm.lib(WINMM.dll); second definition ignored [D:\example\raylib.vcxproj]
raudio.obj : warning LNK4006: PlaySound already defined in winmm.lib(WINMM.dll); second definition ignored [D:\example\raylib.vcxproj]
core.obj : warning LNK4006: CloseWindow already defined in user32.lib(USER32.dll); second definition ignored [D:\example\raylib.vcxproj]
core.obj : warning LNK4006: ShowCursor already defined in user32.lib(USER32.dll); second definition ignored [D:\example\raylib.vcxproj]
Having raylib compiled this way MyProject does not need to link with user32.lib and it works.
What is the best way to use raylib in this situation? Should I always compile raylib with it's dependencies (user32.lib etc.) and get those warnings or maybe I should link with them later when MyProject is compiled (then I need to make sure that raylib is linked before it's dependencies)?

MSVC - Executable builds correctly but DLL doesn't, missing symbols and conflicting dependencies - SSCCE/Repro

I have a working executable here and I'm trying to build a DLL from the same code, but I'm having some strange errors and managed to pinpoint the culprits after a lot of trial an error, I decided to ask for help because I'm really stuck now. I'm linking both SDL2 and Cimgui (Dear Imgui C Wrapper) statically in my code, the executable works perfectly fine:
#include "imgui/imgui.h"
#include "cimgui.h"
#pragma comment(lib, "cimgui.lib")
#include "SDL.h"
#undef main
#pragma comment(lib, "SDL2-staticd.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "imm32.lib")
#pragma comment(lib, "version.lib")
void main()
{
SDL_Init(0);
igCreateContext(0);
printf("OK");
}
So now I switch the project to DLL (I disabled that /IMPLIB option to make sure the only difference in the link command is the /DLL and the extension). When I try to build I get errors regarding cimgui.lib like:
cimgui.lib(imgui_draw.obj) : error LNK2001: unresolved external symbol memcmp
cimgui.lib(imgui_widgets.obj) : error LNK2001: unresolved external symbol memcpy
cimgui.lib(imgui.obj) : error LNK2001: unresolved external symbol memset
Apparently the Visual C runtime isn't being linked anymore, I don't really understand why, I could just add it immediately but let's step back and remove Cimgui from the code:
#include "SDL.h"
#undef main
#pragma comment(lib, "SDL2-staticd.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "imm32.lib")
#pragma comment(lib, "version.lib")
extern "C" __declspec(dllexport) void main()
{
SDL_Init(0);
}
I get 13 errors similar to this:
MSVCRTD.lib(_init_.obj) : error LNK2019: unresolved external symbol _CrtDbgReport referenced in function _CRT_RTC_INIT
So I manually include the libs that contain the missing symbols: ucrtd.lib, vcruntimed.lib, and then the DLL builds fine.
Now I try to add Cimgui again, but it fails to build with errors like these:
MSVCRTD.lib(utility.obj) : error LNK2019: unresolved external symbol __vcrt_initialize referenced in function __scrt_initialize_crt
MSVCRTD.lib(utility.obj) : error LNK2019: unresolved external symbol __acrt_initialize referenced in function __scrt_initialize_crt
the __vcrt definitions are in libvcruntimed.lib, but the __acrt definitions are in libucrtd.lib, which conflicts with ucrtd.lib, and even if I remove ucrtd.lib altogether and try to link just libucrtd.lib, I get errors like:
ucrtd.lib(ucrtbased.dll) : error LNK2005: malloc already defined in libucrtd.lib(malloc.obj)
Which I don't know how to interpret because I'm not linking ucrtd.lib.
I don't really understand why building a DLL isn't just like building an Executable especially because the EXE binary is very similar to the DLL and I could even use it to interop as a DLL but that doesn't feel right. I'm sure there's a way to build this and I just don't know how.
For completeness (and just in case), here are the linker commands for the EXE and DLL:
/OUT:"C:\Projects\BuildTest\x64\Debug\Build.dll" /MANIFEST /NXCOMPAT /PDB:"C:\Projects\BuildTest\x64\Debug\Build.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /DLL /MACHINE:X64 /INCREMENTAL /PGD:"C:\Projects\BuildTest\x64\Debug\Build.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"x64\Debug\Build.dll.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"C:\Projects\cimgui_build\Debug" /LIBPATH:"C:\Projects\SDL2-2.0.8\build\Debug" /TLBID:1
/OUT:"C:\Projects\BuildTest\x64\Debug\Build.exe" /MANIFEST /NXCOMPAT /PDB:"C:\Projects\BuildTest\x64\Debug\Build.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X64 /INCREMENTAL /PGD:"C:\Projects\BuildTest\x64\Debug\Build.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"x64\Debug\Build.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"C:\Projects\cimgui_build\Debug" /LIBPATH:"C:\Projects\SDL2-2.0.8\build\Debug" /TLBID:1
EDIT:
I made a "Minimal, Complete and Verifiable Example" (Self-contained - dependencies included, relative paths, VS2017 project, should compile directly provided you have Windows SDK) and published online here:
https://bitbucket.org/AlanGameDev/buildmvce_so/downloads/
(you can download and extract or clone if you prefer)
If you set the linker flag /VERBOSE to both exe/dll builds and diff the results, you'd get a clue as to what's going on.
In the exe build you'd see
1> Found mainCRTStartup
1> Loaded MSVCRTD.lib(exe_main.obj)
...
1> Found __xi_a
1> Referenced in MSVCRTD.lib(exe_main.obj)
1> Loaded MSVCRTD.lib(initializers.obj)
1>Processed /DEFAULTLIB:kernel32.lib
1> Processed /DISALLOWLIB:msvcrt.lib
1> Processed /DISALLOWLIB:libcmt.lib
1> Processed /DISALLOWLIB:libcmtd.lib
1> Processed /DISALLOWLIB:vcruntime.lib
1>Processed /DEFAULTLIB:vcruntimed.lib
1> Processed /DISALLOWLIB:libvcruntime.lib
1> Processed /DISALLOWLIB:libvcruntimed.lib
1> Processed /DISALLOWLIB:ucrt.lib
1>Processed /DEFAULTLIB:ucrtd.lib
1> Processed /DISALLOWLIB:libucrt.lib
1> Processed /DISALLOWLIB:libucrtd.lib
none of which appear in the dll build. In the dll build you'd see only -
1> Found _DllMainCRTStartup
1> Loaded SDL2-staticd.lib(SDL.obj)
Which is very weird. It seems SDL2 includes its own implementation of the entry point _DllMainCRTStartup, and since the linker takes it from there and not the crt lib - it misses a whole lot of useful /DEFAULTLIB pragmas.
Googling around it seems the _dllMainCRTStartup is included within SDL to satisfy some Watcom needs, and it was already suspected to cause trouble in MSVC.
If you build SDL from sources you should probably just comment out the _dllMainCRTStartup implementation and (hopefully) build successfully.

LNK2019: Unresolved external symbol __imp__ in the .obj file in Line 1

I'm not sure what's going wrong. I'll describe the problem, followed by my understanding of what's going on. It's a simple code:
#include <iostream>
#include <stdio.h>
#include "stdafx.h"
#include <iViewNG-Core.h>
int main(int argc, char ** args) {
iViewVersion version;
iViewRC rc = iView_GetLibraryVersion(&version);
if (RC_NO_ERROR != rc)
printf("ERROR returned by iView_GetLibraryVersion(): %d\n", rc);
printf("The version of the libiViewNG is: %u.%u.%u.%u\n", version.major, version.minor, version.patch, version.build);
return 0;
}
The error description:
Error LNK2019 unresolved external symbol
__imp__iView_GetLibraryVersion#4 referenced in function _main SMI_TrialTests c:\Users\Rakshit\documents\visual studio 2015\Projects\SMI_TrialTests\SMI_TrialTests\SMI_TrialTests.obj
I confirmed that the code is indeed reading iViewNG-Core.h because the auto-fill lets me use functions declared in the file. I did this by adding the lib and include directory correctly in the appropriate VC++ directories. Since this a linker issue, where am I going wrong?
I am new to C++ and I know there are tons of duplicated LNK2019 questions but none of them seemed to solve my problem.
Linker output:
/OUT:"c:\users\rakshit\documents\visual studio
2015\Projects\SMI_TrialTests\Debug\SMI_TrialTests.exe" /MANIFEST
/NXCOMPAT /PDB:"c:\users\rakshit\documents\visual studio
2015\Projects\SMI_TrialTests\Debug\SMI_TrialTests.pdb" /DYNAMICBASE
"kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib"
"advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib"
"odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X86 /INCREMENTAL
/PGD:"c:\users\rakshit\documents\visual studio
2015\Projects\SMI_TrialTests\Debug\SMI_TrialTests.pgd"
/SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'"
/ManifestFile:"Debug\SMI_TrialTests.exe.intermediate.manifest"
/ERRORREPORT:PROMPT /NOLOGO /VERBOSE /LIBPATH:"C:\iView NG
SDK\lib\lib-Windows7-32" /TLBID:1
Examining the symbol __imp__iView_GetLibraryVersion#4, it can be broken into two chunkcs:
__imp_: This means __declspec(dllimport).
_iView_GetLibraryVersion#4: This is the actual symbol, mangled as a C (or extern "C") __stdcall symbol, where the parameters total 4 bytes in size.
Considering this, and going by your code, the function causing the issue is likely:
extern "C" __declspec(dllimport) iViewRC __stdcall iView_GetLibraryVersion(iViewVersion*);
I would suggest checking that the LIB file for the DLL containing this function is being passed to either cl or link (in the former case, cl will pass it to link for you).

visual studio source files building order

i have n number of cpp files in a project.'A' is the source file which will have main function,'B' is an another source file which contains function definition which will be used by 'A'.
A.cpp
#include "stdafx.h"
#include "b.h"
int main()
{
add(5,4);
return 0;
}
B.h
#include "stdafx.h"
void add(int a ,int b);
B.cpp
#include "stdafx.h"
void add(int a,int b)
{
cout<<(a+b);
}
but the build order is like a.cpp after b.cpp so the add function should be unresolved by linker.
how can i solve the build order problem?
Edit 1:my build file log:-
Build started 22-11-2014 15:57:11.
1>Project "C:\Users\Admin\Documents\Visual Studio 2013\Projects\ConsoleApplication2\ConsoleApplication2\ConsoleApplication2.vcxproj" on node 2 (Build target(s)).
1>Link:
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\link.exe /ERRORREPORT:PROMPT /OUT:"C:\Users\Admin\Documents\Visual Studio 2013\Projects\ConsoleApplication2\Release\ConsoleApplication2.exe" /INCREMENTAL:NO /NOLOGO /LIBPATH:D:\Glut /LIBPATH:D:\OpenCV\opencv\build\x86\vc11\lib opencv_core246.lib opencv_features2d246.lib opencv_haartraining_engine.lib opencv_calib3d246.lib opencv_highgui246.lib opencv_imgproc246.lib opencv_legacy246.lib opencv_ml246.lib opencv_objdetect246.lib opencv_video246.lib glut32.lib asmlibrary.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"C:\Users\Admin\Documents\Visual Studio 2013\Projects\ConsoleApplication2\Release\ConsoleApplication2.pdb" /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /LTCG /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:\Users\Admin\Documents\Visual Studio 2013\Projects\ConsoleApplication2\Release\ConsoleApplication2.lib" /MACHINE:X86 /SAFESEH Release\CLM.obj
Release\FCheck.obj
Release\FDet.obj
Release\IO.obj
Release\Patch.obj
Release\PAW.obj
Release\PDM.obj
Release\Tracker.obj
Release\updated_facetracker_v2.obj
Release\glm.obj
Release\glmimg.obj
Release\glmimg_devil.obj
Release\glmimg_jpg.obj
Release\glmimg_png.obj
Release\glmimg_sdl.obj
Release\glmimg_sim.obj
Release\glm_util.obj
Release\stdafx.obj
1>updated_facetracker_v2.obj : error LNK2001: unresolved external symbol "void __cdecl glmDraw(struct _GLMmodel *,unsigned int)" (?glmDraw##YAXPAU_GLMmodel##I#Z)
1>updated_facetracker_v2.obj : error LNK2001: unresolved external symbol "struct _GLMmodel * __cdecl glmReadOBJ(char *)" (?glmReadOBJ##YAPAU_GLMmodel##PAD#Z)
1>C:\Users\Admin\Documents\Visual Studio 2013\Projects\ConsoleApplication2\Release\ConsoleApplication2.exe : fatal error LNK1120: 2 unresolved externals
1>Done Building Project "C:\Users\Admin\Documents\Visual Studio 2013\Projects\ConsoleApplication2\ConsoleApplication2\ConsoleApplication2.vcxproj" (Build target(s)) -- FAILED.
Build FAILED.
Time Elapsed 00:00:00.81
this is the original projects build file here glm.c is compiled built after the updated_facetracker_v2.cpp file and glm.c did not have any error."
Your linker fais, because B.cpp doesn't compile. The compiler fails to create an object for B.cpp. Since the object isn't there, the linker can't find it, and gives the error. There should be an error about B.cpp further up the error log.
Change B.cpp from:
#include "stdafx.h"
void add(int a,int b)
{
cout<<(a+b);
}
to:
#include "stdafx.h"
#include <iostreams>
void add(int a,int b)
{
std::cout<<(a+b) << std::endl;
}
Build order doesn't matter: The compiler takes each source file and creates an object file. The linker takes the object files and tries to link those to your target executable. The order your compiler generates the object files shouldn't matter.
Also, your main is faulty too:
change:
add(5+4);
to:
add(5, 4);
You are trying to link against add(int) while your function in B.cpp has the signature add(int, int) which is a different function according to the linker.

Which compilation options should I use to link with Boost using cl.exe?

I have a program which I would like compile using cl.exe on the command-line. This program depends on some boost libraries which I fail to link to.
The error I'm getting is:
cl /Fosamples\proxy\proxy.obj /c samples\proxy\proxy.cpp /TP /O2 /EHsc
/DBOOST_ALL_NO_LIB /DBOOST_THREAD_USE_LIB /DBOOST_SYSTEM_USE_LIB
/DBOOST_USE_WINDOWS_H /DTAP_ID=\"tap0901\" /D_WIN32_WINNT=0x0501 /MD /nologo
/Isamples\proxy /Iinclude proxy.cpp
link /nologo /MD /OUT:samples\proxy\proxy.exe /LIBPATH:samples\proxy
/LIBPATH:lib asiotap.lib libboost_system-vc100-mt-1_47.lib
libboost_thread-vc100-mt-1_47.lib ws2_32.lib gdi32.lib iphlpapi.lib
advapi32.lib samples\proxy\proxy.obj
LINK : warning LNK4044: unrecognized option '/MD'; ignored
asiotap.lib(bootp_builder.obj) : error LNK2001: unresolved external
symbol "class boost::system::error_category const & __cdecl
boost::system::system_category(void)"
(?system_category#system#boost##YAAEBVerror_category#12#XZ)
I compiled Boost, using the following command-line, from the x64 MSVC command prompt:
.\b2.exe install toolset=msvc --prefix=C:\Boost-VC-x64
If I look inside libboost_system-vc100-mt-1_47.lib I can see that:
?system_category#system#boost##YAABVerror_category#12#XZ
Is exported. But If you look closely it differs a bit from the one in my compilation errors:
?system_category#system#boost##YAAEBVerror_category#12#XZ // The symbol I miss
?system_category#system#boost##YAABVerror_category#12#XZ // The exported symbol
I guess I should either change Boost or my compilation options but fail to figure what to change exactly. Any clue ?
Thank you very much.
After some investigations, I realized that I compiled Boost for a x86 platform where I was linking with a x64 binary.
I thought that compiling Boost inside a Visual Studio x64 command prompt was enough but you actually have to specify:
.\b2.exe install toolset=msvc address-model=64 --prefix=C:\Boost-VC-x64
To make it work.