Under Visual Studio (2017) I am trying to script a C++ program with Lua 5.3 but the linker does not find three function names referenced in my C++ source file:
unresolved external symbol _lua_close
unresolved external symbol _lua_createtable
unresolved external symbol _luaL_newstate
I took the C++ source from the Lua website.
I downloaded the Lua 5.3 dynamic library which does not come with an import library so I created the import library with the MSVC tools like so:
dumpbin /exports E:\Documents\Programmation\Lua5.3\lua53.dll
From the output of dumpbin, I copied the 146 names in a new file "mylua53lib.def" and ran lib to generate the .lib file like so:
lib /def:E:\Documents\Programmation\Lua5.3\mylua53lib.def /OUT:E:\Documents\Programmation\Lua5.3\mylua53lib.lib /machine:x86
The three function names that the linker does not find are indeed not appearing in the output of the dumpbin command.
A binary distribution of Lua intented for dynamic linking on Windows should come with two binary files:
a DLL file with the actual Lua code
a library file with the method stubs delegating to the DLL
Sometimes the library file will come with an .a extension, which is more common on Linux (as opposed to .lib on Windows). If it's a Windows build, though, you can simply pass that file as a linker dependency and it will work just fine. This question deals with differences between the two conventions.
As a side note, in order to make it work, if you create a C++ project in Visual Studio, and add a Source.cpp as it suggests by default, you'll still get unresolved externals. This is due to the fact that while the C sources compile as C++ code just fine, the linker will expect mangled names for the definitions of the C functions used. This can be prevented by either compiling the file as C code, or, preferrably, by telling it that the names from Lua headers should be unmangled in the linked library using extern "C":
extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include <stdlib.h>
#include <stdio.h>
}
Related
I cannot get a DLL to link, that needs a class exported from the app this DLL will be used with. Visual Studio 2008, Windows 7.
I had a small sample DLL compiling (the default MSFT DLL project actually), and the app can use LoadLibrary() and GetProcAddress() on it correctly. I'm experienced with dllimport/dllexport. Using dumpbin /exports was critical to discover the mangled names to use with GetProcAddress() (MSFT's default empty DLL includes a sample function without extern "C") but this is a solved problem.
The next step was to have the app export a class that the DLL will need to subclass. I do the dllimport/dllexport #define's in the reverse sense from usual: a special symbol when the app is compiled tags the class with dllexport and non-app code (such as the DLL) using that header, without the special symbol, gets a dllimport spec. dumpbin /exports on the .exe file shows exactly this class's (mangled) symbols being exported, and no others, as expected.
The next step was to have the DLL include the header and create an object of the exported object's type (as a baby-step towards actually subclassing it). Compiles fine, but linker shows error:
DynTest.obj : error LNK2019: unresolved external symbol "public: __thiscall Test::Test(class Toast*,double)" (??0Test##QAE#PAVToast##N#Z) referenced in function "public: __thiscall CDynTest::CDynTest(void)" (??0CDynTest##QAE#XZ)
OK, that didn't surprise me, as I know on WIN32 I need to supply DLL's at link time to make a DLL, unlike my usual Unix. Since Windows seems to treat DLLs and executables a bit similarly, I tried adding the .exe at Properties->Configuration Properties->Linker->Input->Additional Dependencies. That gets an error that looks like LINK.EXE didn't auto-detect that it was being given an .exe:
T:\mypath\MyBinary.exe : fatal error LNK1107: invalid or corrupt file: cannot read at 0x348
I then tried adding instead the object file that defines this class... That seems to be understood by the linker, and is probably successfully satisfying the DLL's need to link, but now shows a myriad of other symbols this file depends upon.
So I've considered refactoring the app such that most of it is in a DLL or LIB, just so I can supply that as an "Additional Dependencies" to the DLL I'm actually worried about. But this seems to be draconian. Is that my only option?
Invoking dumpbin /exports gives you a list of mangled names of exe exports. You need to create a module definition file (.def) containing these names:
EXPORTS
#d3d_some_fancy_mangedled_method_1
#d3d_some_fancy_mangedled_method_2
...
Notice that it is basically dumpbin output with first columns removed.
Then you use lib tool to generate export library from module definition file:
LIB /DEF:prog.def /NAME:prog.exe /MACHINE:x86
Finally you link generated export library prog.lib into your application. /MACHINE option should match to your executable. Notice that you don't need to link or anyhow use program executable to link it, only export library is used.
I'm making a C++ program and I want to use FFmpeg pre-built for x64, which is a C-compiled library.
I'm using this code in order to include its header:
extern "C" {
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#pragma comment (lib,"G:/Documents/ffmpeg/lib/avcodec.lib")
#pragma comment (lib,"G:/Documents/ffmpeg/lib/avformat.lib")
}
I'm then calling the symbols like I would do for a normal function, for example with av_interleaved_write_frame(out->formatContext, &packet);
However, when I try to compile it with Visual Studio 2015's built-in C++ compiler, I get a lot of error like
Error LNK2019 unresolved external symbol _av_write_trailer referenced in function "void __cdecl closeArenaVideo(struct VideoOutput *)" (?closeArenaVideo##YAXPAUVideoOutput###Z) Sparta2 c:\Users\Théo\documents\visual studio 2015\Projects\Sparta2\Sparta2\video.obj
for basically any of the symbols I'm refering to.
I tried to import everything in Visual Studio, to compile with command-line, to manually put FFmpeg's libraries in the default libraries path, without success.
Thank you in advance!
A typical problem which is hard to understand from quoted linker errors is the problem of referencing wrong .lib files, esp Win32 platform libraries in x64 build and vice versa. The names might be correct, but the set is wrong and then linker takes the #pragma references but ignores the content.
You should make sure that your build platform matches the bitness of referenced library files. This answer has minimalistic project which does build well and you can compare code/references to what you use, and it also mentions bitness problem as well in the very bottom and comments to the answer.
I am using Octave within MSVC 2010. First I downloaded Octave latest version at this link. After installing, I tried to run this simple code:
#include <iostream>
#include<octave-3.6.4\octave\oct.h>
#include<octave-3.6.4\octave\config.h>
#include<octave-3.6.4\octave\octave.h>
using namespace std;
int main (void)
{
std::cout << "Hello Octave world!\n";
system("PAUSE");
return 0;
}
Note that I added these links to my project as well:
C:\Software\Octave-3.6.4\include\octave-3.6.4\octave--->Includ. Dir.,
C:\Software\Octave-3.6.4\include--->Includ. Dir.
C:\Software\Octave-3.6.4\lib--->Lib. Dir.
C:\Software\Octave-3.6.4\lib\octave\3.6.4--->Lib Dir.
I also added 1 and 2 to Additional Inc Dir!!
C:\Software\Octave-3.6.4\lib\octave\3.6.4--->Additional Lib. Dir in Linker.
First, I got this error that it cannot find math.h in Program Files while this file was in my Program Files (x86). So, I changed it to: C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\math.h and it solved this error. However, now I get this error:
error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall octave_value::~octave_value(void)" (__imp_??1octave_value##QAE#XZ) referenced in function "public: void * __thiscall octave_value::`vector deleting destructor'(unsigned int)" (??_Eoctave_value##QAEPAXI#Z)
It is not sufficient to add the library path to the project.
You have to add the library name(s) (including .lib) to the "Additional Dependencies" in the Linker/Input tab.
Edit
To verify what library has been searched you can enable the Linker/General/Show Progress option. Then you can see in the Build Output what library has actually be used in symbol search.
Edit
Your example code doesn't show any instance of an array of octave_value instances. So it's a bit surprising that you need to link with any library with the code you've shown. But anyway you want to have these externals resolved.
If there is no other resource (manual, ...) you should detect where the octave_value class is implemented. This can be a static library or a DLL.
You can detect the DLL implementation with a dumpbin /exports on the DLLs. In that case you need the corresponding import libraries. The LIB should have the same base name as the DLL. Verify that you have added that dependency and how the linker searches this library for symbols.
The name of the symbols __imp_??1octave_value##QAE#XZ indicates that it should be in a DLL. But since you have a problem you might want to search LIBs too.
You can detect the LIB implementation with a dumpbin /symbols. In that case you have to add the LIB directly. Again verify it with the Build Output.
The dumpbin output will probably very verbose. You should use either findstr to limit the output or redirect the output to a file and search the symbols with an editor of your choice.
Search for ocatave_value. If you find a different decoration of the constructor and destructor you might have missed to set an option. A preprocessore directory could be used to define how the library is use. E.g. if you find octave_value::octave_value without the __imp_ prefix you have accidentily compiled for a DLL version altough the class is implemented in a static library. In that case, read the manual and ask at the octave mailing list forum or whatever.
I have a VS2013 project with a class in a separate file where I want to
use the BeaEngine to disassemble a binary. I added all the necessary
files (BeaEngine.h and BeaEngine.lib) to the project and set the linker
to include the .lib. When I call the Disasm function from inside the
main() function my project compiles just fine, but when I try to call it
from inside one of the member functions of my class, I get the following
error:
error LNK2019: Verweis auf nicht aufgelöstes externes Symbol
"__imp__Disasm" in Funktion
""private: void __thiscall BinaryBlob::callScan(unsigned int,unsigned int)"
(?callScan#BinaryBlob##AAEXII#Z)"
So to me it looks like the linker cannot find the implementation for the Disasm function.
If I comment the following line out it will compile without an error.
len = Disasm( &(this->disasm) );
My includes are like follows:
#include "stdafx.h"
#include "BinaryBlob.h"
#define BEA_ENGINE_STATIC /* specify the usage of a static version of BeaEngine */
#define BEA_USE_STDCALL /* specify the usage of a stdcall version of BeaEngine */
#include "BeaEngine.h"
Do I need to do something else besides including the BeaEngine.h?
Any help would be really appreciated!
What this says is that the compiler can see the .h file (it recognizes the .h file name) but is not linked to the library itself. I'm using VC10 but you should need to do something like
Property Pages,
General, then add the directory of the lib under Additional Library Directories
then
Input,
Additional Dependencies, put the name of the library mylib.lib
If it's a .dll either just put it with the .exe of your program or add the path of the .dll to your system PATH
Basically it's like a lawn mower: If it's getting air, gas and a spark it will run.
Air = .h file
Gas = linked to .lib or .dll (or other things on Linux)
Spark = Your program calling the lib
I am trying to get the ARPACK library to run on VS2010.
I would like to use the C++ wrappers
provided by ARPACK++ (some background - i need to get eigenvalues and eigenvectors of huge matrices). There is a very good tutorial on the subject here.
Following the
tutorial i've managed to compile the fortran code using g77 on mingw, i successfully generated
the dll and lib as described. The problem arises when trying to link my visual studio project to the library.
The way i'm trying to link is as follows:
I've made a simple VS2010 C++ console app
i've added the the folder containing ARPACK++ libraries to my "additional include folders"
i've added the lib file to "Additional dependencies"
i've added the directory containg the lib file to my "Additional library directories"
Despite these settings when i try to compile this short test code:
#include "stdafx.h"
#include "arrsnsym.h"
int _tmain(int argc, _TCHAR* argv[])
{
ARrcNonSymStdEig<float> prob(100, 4L);
printf("Bok!");
return 0;
}
I get an error saying:
>arpackcpp.obj : error LNK2001: unresolved external symbol scopy_
1>arpackcpp.obj : error LNK2001: unresolved external symbol snaupd_
1>arpackcpp.obj : error LNK2001: unresolved external symbol sneupd_
I do not understand why the linker can't find the mentioned methods. Inspecting
the .def file generated by the dllwrap utility does indeed mention all these functions
so i am fairly sure they should be available. Still, i feel i'm missing something obvious.
UPDATE (got it working!):
It turns out that i was trying to link a 64 bit program to a 32 bit library, when switching
to x86 in the Configuration settings AND including the generated def file in Configuration Properties -> Linker -> Input -> Additional definition file, it worked for 32bit (however i needed 64). The final solution that worked for me was to cross compile it for Win64 using MinGW and gfortran on linux. That worked surprisingly well and produced a dll to which i could link from a 64bit C++ app in VS. I think i should now go write a tutorial on how to do this :)
My guess is that this is a name-mangling scheme issue. In fortran, it is not well defined what name the symbols will have in the object file's symbol table. For example, a routine named foo could end up in the symbol table as foo,FOO,foo_,foo__ and so on. These days, I don't know of too many compilers that use double underscores (with g77 being the exception). I'm assuming the ARPACK++ wrappers are assuming a single underscore. The solution here is to tell the compiler to use single underscores in the symbol names (with g77, that means using -fno-second-underscore). Note that gfortran is a newer (still supported) open-source fortran compiler which does single underscoring by default. You might want to try to build your code using that compiler as well. (It might produce more optimized output than g77.)