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).
Related
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.
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.
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.
I am trying to do a simple c style function export and import with visual studios 2012. I made two projects. My ultimate goal is to call c++ functions from a Fortran program, so I'm trying to make the dll as straightforward as possible. The first project simply contains 1 file which has this code:
#include <stdio.h>
extern "C" __declspec(dllexport) void __cdecl hello()
{
printf("Hello, World!\n");
}
This is compiled as a .dll. I then include that in the linking input to the second project which simply contains a file with this:
extern "C" __declspec(dllimport) void __cdecl hello();
int main(int argc, char *argv[])
{
hello();
return 0;
}
When i link without common language runtime support i get the error:
Error 1 error LNK1107: invalid or corrupt file: cannot read at 0x2B8
If i compile with common language runtime support i get the error:
Error 1 error LNK1302: only support linking safe .netmodules; unable to link
To fix that the internet wants me to compile with /clr:pure or /clr:safe, but my vs tels me that doesnt work with c style exports.
my linking command line call is currently:
/OUT:"c:\users\kevin\documents\visual studio 2012\Projects\Project1\Release\Project2.exe" /MANIFEST /NXCOMPAT /PDB:"c:\users\kevin\documents\visual studio 2012\Projects\Project1\Release\Project2.pdb" /DYNAMICBASE "c:\users\kevin\documents\visual studio 2012\Projects\Project1\Release\*" "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 /OPT:REF /SAFESEH /PGD:"c:\users\kevin\documents\visual studio 2012\Projects\Project1\Release\Project2.pgd" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Release\Project2.exe.intermediate.manifest" /OPT:ICF /ERRORREPORT:PROMPT /NOLOGO /TLBID:1
Thanks in advance for you help.
Also, if any of you understand linking between fortran and c better then me do i want /clr when making the .dll to link with fortran (i assume that I don't)?
Shared library consists of two files on Windows. A .dll and a .lib. You have to provide the .lib one as linker input and you have to put the .dll in the same directory as the executable or somewhere in %PATH% at runtime.
I'm working on a project where I have to grab some of the classes and put them into a shared library. The shared library takes care of REST calls and will be used by the main project.
The *.pro file for the shared lib looks like this:
QT += network
QT -= gui
TARGET = MyQtFramework
TEMPLATE = lib
DEFINES += MY_LIBRARY
SOURCES += \
storageprovider.cpp \
handler.cpp
HEADERS += \
myframework_global.h \
storageprovider.h \
handler.h
INCLUDEPATH += "../Shared"
INCLUDEPATH += "E:\src\Lib\Boost\Current"
INCLUDEPATH += "E:\src\Lib\CryptLite\Current"
INCLUDEPATH += "E:\QT"
LIBS += -L"E:\src\Lib\Boost\Current"
And the command line from visual studio looks like this:
/OUT:"debug\MyQtFramework.dll" /NOLOGO /LIBPATH:"E:\QT\4.8.0\lib" /LIBPATH:"E:\src\Lib\Boost\Current" /LIBPATH:"E:\src\Lib\Boost\Current\lib\debug" /DLL "E:\QT\4.8.0\lib\QtNetworkd4.lib" "E:\QT\4.8.0\lib\QtCored4.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 /ManifestFile:"Win32\MyQtFramework.dll.intermediate.manifest" /ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"PROJECTPATH\debug\MyQtFramework.pdb" /PGD:"PROJECTPATH\debug\MyQtFramework.pgd" /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:QUEUE
Here I cannot see any flags that specifies that it is a library and how it is exported.
I then create a global header for the shared library "g_global.h":
#ifndef G_GLOBAL_H
#define G_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(MY_LIBRARY)
# define SHARED_EXPORT_IMPORT Q_DECL_EXPORT
#else
# define SHARED_EXPORT_IMPORT Q_DECL_IMPORT
#endif
#endif
And all my other headerfiles looks like this:
#include "g_global.h"
class SHARED_EXPORT_IMPORT storageProvider : public QObject {
....
So far so good right? This compiles in Visual Studio 2010 and doesn't give any errors. The issue is when I try to use it in my main project. I then INCLUDEPATH and the LIBS whiche the include path points to where the headerfiles for the shared lib are located and the Libs where the *.lib file is. These settings are done on the visual studio property page, not in the *.pro file.
The I include the global header, which works. When I include the "storageProvider.h" I get 7 linking errors, here are two of them:
Error 6 error LNK2001: unresolved external symbol "public: virtual int __thiscall storageProvider::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall#storageProvider##UAEHW4Call#QMetaObject##HPAPAX#Z) E
Error 2 error LNK2019: unresolved external symbol "__declspec(dllimport) public: void _thiscall storageProvider::put(class QString const &,class QString const &,class QPointer,int)" (_imp_?put#storageProvider##QAEXABVQString##0V?$QPointer#VQIODevice####H#Z) referenced in function "public: void __thiscall FileUploader::uploadNext(void)" (?uploadNext#FileUploader##QAEXXZ)
I don't know how to be able to include the storageProvider and use it.
Notice: I renamed all the functions and classes, so if something seems to be wrong, please point it out, but it might just be a misstake I made when I renamed things.
Commandline for the main project:
/OUT:"debug\myapp.exe" /NOLOGO /LIBPATH:"E:\QT\4.8.0\lib" /LIBPATH:"e:\QT\4.8.0\lib" /LIBPATH:"E:\src\Lib\Boost\Current" /LIBPATH:"E:\src\Lib\Boost\Current\lib\debug" /LIBPATH:"FILEPATH\MyQtFramework\Debug" "E:\QT\4.8.0\lib\qtmaind.lib" "E:\QT\4.8.0\lib\QtDeclaratived4.lib" "E:\QT\4.8.0\lib\QtGuid4.lib" "E:\QT\4.8.0\lib\QtNetworkd4.lib" "E:\QT\4.8.0\lib\QtCored4.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 /ManifestFile:"Win32\myapp.exe.intermediate.manifest" /ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"FILEPATH\myapp\debug\myapp.pdb" /SUBSYSTEM:WINDOWS /PGD:"FILEPATH\myapp\debug\myapp.pgd" /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:QUEUE
In the command line you posted for the creation of myapp.exe I see the configuration fo the libpath, /LIBPATH:"FILEPATH\MyQtFramework\Debug" but I don't see MyQtFramework.lib as an input file.
You need to specify that as well.