C++ static library using functions defined in another cpp project - c++

I am working on a VS 2012 project and i am using an already compiled static library (that was compiled in VS 2013). The library references the "vacopy" method that is VS 2013 compatible but not found in VS 2012.
When I compile my cpp project, I get the linking error : error LNK2019: unresolved symbol __imp___vacopy
My first reflex was to add the declaration and definition of va_copy in my project, so I included the following:
in a header file :
void va_copy(va_list dest, va_list src);
in a cpp file :
void va_copy(va_list dest,va_list src)
{
dest = src;
}
But this didn't resolve the problem, I still get the same linking error.
Thanks in advance for your answers.

You basic problem is that the library was compiled to link with standard libraries in a DLL (thus the __imp__); you application is probably set differently (to grab standard calls from a statically linked in library).
You either have to match your compiler settings (in this case project properties -> C/C++ -> Code Generation section) where you can specify to use DLL or static options.
It's often worth checking if there is a way to specify to the include files which version of the link you need - some libraries (CURL for example) allow you to define compiler predefines to control exactly which functions are linked to.

Related

What do I need to include to avoid an Unresolved external symbol error trying to export a VST3?

I'm currently attempting to compile a VST3 plugin (or any C++ code, for that matter) for the first time, mainly just following Steinberg's own tutorial for all things except the actual sound processing.
Attempting to compile throws an "unresolved external symbol" error:
Error LNK2019 unresolved external symbol "public: __cdecl VSTGUI::VST3Editor::VST3Editor(class Steinberg::Vst::EditController *,char const *,char const *)" (??0VST3Editor#VSTGUI##QEAA#PEAVEditController#Vst#Steinberg##PEBD1#Z) referenced in function "public: virtual class Steinberg::IPlugView * __cdecl Itisdud::Split_TimesController::createView(char const *)" (?createView#Split_TimesController#Itisdud##UEAAPEAVIPlugView#Steinberg##PEBD#Z) Split_Times D:\programme\VST3Dev\Split_times\Split_Times\build\split_timescontroller.obj 1
The function that causes this, createView, is still the default it is when created by the Project Generator:
IPlugView* PLUGIN_API Split_TimesController::createView (FIDString name)
{
// Here the Host wants to open your editor (if you have one)
if (FIDStringsEqual (name, Vst::ViewType::kEditor))
{
// create your editor here and return a IPlugView ptr of it
auto* view = new VSTGUI::VST3Editor (this, "view", "split_timeseditor.uidesc");
return view;
}
return nullptr;
}
Copying the createView function from the again and adelay samples didn't work either.
As the Project generator only includes vstgui4/vstgui/plugin-bindings/vst3editor.h and not the vst3editor.cpp file, I tried including that as well (As I've read that not having the actual implementation there might be the cause of the issue), however that didn't fix the issue but made a lot of other errors happen upon compiling.
I also tried to follow this, including the cpp files noted there and changing the createView function to what is written there, however this also only led to there being a bit more than 300 errors upon compiling.
Copying the includes from the again sample didn't work either.
What would I need to include for this to work?
Those are the linker errors as you didn't instruct the linker where to find the required library files whose functions you are using.
Remember that compilation is a 2-step process that involves compilation and linking so it is best to separate them.
Lets assume you are using Visual Studio on Windows, and lets assume your VST SDK is installed on
C:\VST3SDK.
The first thing you should do is fire-up Visual Studio and select File->Open->CMake and go locate the CMake.txt file here
C:\VST3SDK\VST3_SDK.
After this file is loaded you will find on Visual Studio Solution Explorer a list of ready-made projects that come with the VST SDK loaded.
You will find that one of these projects is called Libraries and that is THE first action you have to do.
Now you have to build the correct library depending on whether you want to make 32-bits or 64-bits VSTs and you should set the configuration of the Libraries project accordingly.
You will build these libraries and if you hadn't changes any setting the libraries will be found at
C:\VST3SDK\VST3_SDK\out\build\x64-Debug\lib
or
C:\VST3SDK\VST3_SDK\out\build\x64-Release\lib
the necessary libraries being:
base.lib
pluginterfaces.lib
sdk.lib
sdk_common.lib
sdk_hosting.lib
vstgui.lib
vstgui_standalone.lib
vstgui.support.lib
vstgui_uidescription.lib
The above step ensures that you now have the necessary library files your VSTs will depend on.
Now assuming you have a VST sample project, lets say that you got from Git-hub and that it were written and setup correctly to run on Visual Studio, i.e. it came with a
myVST.vcxproj file.
Then you could paste the following pragmas on a prominent VST file such as the factory.cpp
#pragma comment(lib, "base.lib")
#pragma comment(lib, "pluginterfaces.lib")
#pragma comment(lib, "sdk.lib")
#pragma comment(lib, "sdk_common.lib")
#pragma comment(lib, "sdk_hosting.lib")
#pragma comment(lib, "vstgui.lib")
#pragma comment(lib, "vstgui_standalone.lib")
#pragma comment(lib, "vstgui_support.lib")
#pragma comment(lib,
"vstgui_uidescription.lib")
(Had to abbreviate due to confusing formatting requirements of this site but replace like "vstgui.lib" with a fully qualified path like
"C:/VST3SDK/VST3_SDK/out/build/x64-Debug/lib/vstgui.lib"
Now if your project properties
C/C++ _> General _> Additional Include Directories has correct entries that will tell the compiler the paths it will find ALL the #include files, then you will find that if you right click on any compilable file (c, cpp, rc ...) and select Compile then the file should successfully compile into an object file without any Compiler errors otherwise it is an indication that the compiler cannot find the required header
files.
But the problem you face are the linker problems, the linker can not find the required libraries of functions you have used in your project and the solution is just pasting the pragmas above.

link static library in c++ visual studio

can someone please help me to understand the process.
in c++ visual studio 2010
i have a visual studio solution (lets call it mysol)
i have a project built as a static library (let's call it staticprj)
staticprj needs to use a library from outside (lets call it ext.lib)
in the body of the source code of staticprj i include outside library header file with
# include extlib.h and make calls to some of its functions (let call them extfunctions())
i also include the the path to the header files location of the ext.lib.
the staticprj compiles okay without errors
the mysol also has another project which is a dynamic library (dynprj) and which depends on the staticprj.
also in the source files of the dynprj uses functions from outside library.
i have included #include extlib.h in the source code of dynprj.
i have included the path of the header files
i have attached extlib.h directly to the dynprj
i have also added ext.lib to the linker input (along with the path where the ext.lib resides).
i still get a lnk2001 error stating that extfunctions() where not found.
the whole structure (the mysol solution) compiles okay if i do not use ext.lib at all.
my question is how does the linking process works and what can i do to correct this linking error.
(note that without the presence of ext.lib my linking of the staticprj and dynprj is fine. my compilation works okay and my code works. i only get the linking error when i try to link another ext.lib to staticprj and dynprj and use functions from ext.lib)
thanks in advance.
I'm not quite sure it will work, but try putting the .dll inside your "mysol" debug folder. I had a similar problem couple of weeks ago when I had library compiled as .dll. I just placed that .dll within my debug folder and worked lovely.

Lesson needed on how to work with files in different projects in C++

I have been able to work in the same project for sometime now, writing and successfully running c++ code. However, I discovered that I am still missing some essentials on how to export my .h files to another project and successfully use them in there.
I created a second project, project B to test the classes I have in project A.
visual c++: #include files from other projects in the same solution
I added the path of the header file in Project A into the Additional Include Directories(C\C++>general and Linker>general) section in the project configuration of Project B. I tried following the tutorials on this page http://msdn.microsoft.com/en-us/library/ms235636.aspx but I still end up with the error below
** LINK : fatal error LNK1104: cannot open file 'C:\Users\LaC\Projects\OSGB\Debug\OSGB.lib**
I would appreciate any help in understanding exactly how this is done so that in future, when I encounter this problem, I can know how to troubleshoot.
The code below is all I am working with.
IN PROJECT A
=============
//Utility.h
class Utility
{
private:
protected:
public:
Utility(void);
~Utility(void);
double square_root (const double);
};
//Utility.cpp
#include "StdAfx.h"
#include "Utility.h"
Utility::Utility(void)
{
//do nothing for now
}
Utility::~Utility(void)
{
//do nothing for now
}
double Utility::square_root (const double)
{
return 0;
}
IN PROJECT B
===============
#include "gtest/gtest.h"
#include "Utility.h"
TEST (SquareRootTest, PositiveNos) {
Utility u;
EXPECT_EQ (50.3321, u.square_root (2533.310224));
}
There are two (general) ways to include files into your project:
Make them a part of your project (adding them from the solution explorer) OR
Import them as a library (static or dynamic linking)
If you make them part of your project, then you have to add the header and the source files in order for the project to compile correctly. However, that's usually not what you want to do, as it defeats the purpose of having external libraries.
The second case is to use the external libraries, which requires that you:
Include the header files which are exported by the library in your C++ properties.
For static linking: you also have to include the *.lib file (the output of building the library) in the Linker properties.
OR
For dynamic linking: see tutorial.
So remember: there are two parts to building a C++ project- compiling and linking.
Compiler Errors:
If you get an error whose code starts with C* (e.g. C1083) and is related to problems header with the files, then check the Properties-> C/C++ -> General -> Additional Include Directories.
Linker Errors:
If you get an error whose code starts with LNK*, then check
Properties -> Linker -> General -> Additional Library Directories (make sure that this points to where the *.lib file is located)
AND
Properties -> Linker -> Input -> Additional Dependencies (make sure that the *.lib file is added here).
If you're dynamically linking, then check that you're correctly referencing the DLL.
So in your case, you have to determine if you're linking statically or dynamically and then make the appropriate references. So ware you getting those header files from a dynamically library or a static library?
When the linker emits unresolved external symbol for a symbol that lives in another library (DLL or shared library), this indicates that you need to link your app to that other library's .lib file. That is most likely what's happening here.
For more information see:
(MSDN) Walkthrough: Creating and Using a Dynamic Link Library (C++)

Getting FreeImage to work with Visual Studio 2010

I was advised by some of you not to long ago to use FreeImage as a library for image processing in C++.
I now have some trouble in getting the library to work (still relatively new here).
I've tried loading the various vcxproj and sln tiles and they gave me a blank project. Since there isn't any installation instructions provided for that, I gave up on making it a visual studio solution.
I next tried the old-fashion way of compiling the source code using the Makefile and then adding "FreeImage/Source" to the linker. While the IDE does not raise any red flags when I call functions declared in FreeImage.h, it gave me a bunch of "error LNK2019: unresolved external symbol" during compilation, as if the functions do not exist. What I suspect is that the IDE could not find the .cpp files that define the said functions, but I still get that same problem when I added FreeImage/Source/FreeImage to the linker.
Now when I directly included some of the .cpp files (i.e. Plugin.cpp and FreeImage.cpp) for a test, I get even more unresolved external symbol errors as well as things like "inconsistent dll linkage" for this within... for example FreeImage.cpp:
const char * DLL_CALLCONV
FreeImage_GetVersion() {
static char s_version[16];
sprintf(s_version, "%d.%d.%d", FREEIMAGE_MAJOR_VERSION, FREEIMAGE_MINOR_VERSION, FREEIMAGE_RELEASE_SERIAL);
return s_version;
}
So, I am totally stuck. What am I doing wrong? I felt I've followed the adequate steps in adding library dependencies, such as adding the specific folders that are immediate parents to the relevant .h and .cpp files in C/C++ -> General -> Additional Included Directories and Linker -> General -> Addition Library Directories.
Some help will be greatly appreciated!
Using FreeImage v3.15.3 I had no problems converting the VS2008 project to VS2010.
Also the building worked as expected. But when I linked to the static lib, I got some unresolved externals. First I tried al kinds of tricks setting /MT /MD linking, but that did not solve these linking problem.
After reading Some Newbie's comment I dug into freeimage.h. There I found a macro switch FREEIMAGE_LIB that controls the calling conventions of the function.
Use a #define FREEIMAGE_LIB before including the freeimage.h file. That way you can easily static link to FreeImage.lib

Dynamic linking in Visual Studio

I have to link dynamically with OpenSSL libeay32.dll.
I'm writing native c++ console application using Visual C++ Express 2008.
I'm including a header evp.h from OpenSSL distribution. Building and...:
error LNK2001: unresolved external symbol _EVP_aes_256_cbc
error LNK2001: unresolved external symbol _EVP_DecryptInit
error LNK2001: unresolved external symbol _EVP_CIPHER_CTX_init
How to make calls to libeay32.dll methods? I don't know where to specify it's filename
There is probably a .lib file you also need to add to your compiler's linker input. Check the documentation for the library you're using.
Try using Win32 API's LoadLibrary function, the following link might be of some help :example
if your application need to be able to run without the existence of OpenSSL, use dynamic linking with explicit run-time linking and handle the cases when the DLLs are not around (e.g. by changing your application's behavior / switching to other libraries).
I recently found a nice examples on this:
Google Gears WinCE Geolocation API
itsutils
if your application may only run if the OpenSSL exist in the environment (or you ship the DLL), use implicit run-time linking.
For MSVC, the simplest is to add #pragma comment(lib,"libeay32.lib") in your source code (You will probably need the .lib stub to be produced by the same compiler you use)
if your application need to be independent of the environment. Link OpenSSL statically (also uses .lib).
Note that there are 2 kinds of .lib. The first is used for dynamic but implicit linking, second is for static linking. The one for dynamic implicit linking contains stubs that load the DLL for you whereas the one for static linking contain the actual implementation.
In the project properties, configuration properties, linker, input - add the library name under "additional dependencies".
[Note, this will actually STATICALLY link with the library. If you truly want to load the library dynamically you will need to call LoadLibrary() on the DLL and then get function pointers for the functions you need using GetProcAddress().
See for example
http://msdn.microsoft.com/en-us/library/ms886736.aspx
and
http://msdn.microsoft.com/en-us/library/ms885634.aspx
If you are calling a method from the dll, you can use explict dynamic linking method.
Mistake: you are including a header evp.h from OpenSSL distribution dll to your prohject
As you are linking dynamically, no need to include .h from A DLL to your project.
You can call by following method:
LoadLibrary("libeay32.dll"); /* syntax: */
Declare a function pointer pointing to the function you want to call.
For eg.
Let your libeay32.dll has an exported function: int add(int x, int y);
Then to call it in your project declare a function pointer and then call the method add as follows:
typedef int (*AddfnPtr)(int num1, int num2);
int num1 = 2, num2 = 3 ;
HMODULE handle = NULL;
handle = LoadLibrary("libeay32.dll");
if (handle != NULL)
{
AddfnPtr addfnptr = (AddfnPtr)GetProcAddr(handle, NULL);
if (addfnptr != NULL)
{
int res = addfnptr(num1,num2);
cout << "res = "<<res;
}
}