Linking to visual studio dynamic library - c++

I am trying to create a dynamic library and use it in a console application. The library is Multisite.lib.
My problem is that when I add the project as a reference and add the header files directory it works well, however, when I try to use this library in an independent project I get the unresolved external symbol error.
What I did in the independent project is to add the library to the Linker > Input > Additional Dependencies and add the header directories
#pragma once
#ifndef MultiSite_IMPORTS
#define MATHLIBRARY_API extern "C" __declspec(dllexport)
#else
#define MATHLIBRARY_API extern "C" __declspec(dllimport)
#endif
#define STACKMODE __stdcall
#include <string>
struct interfaceManager;
MATHLIBRARY_API interfaceManager* STACKMODE createInstance();
MATHLIBRARY_API void STACKMODE bert_init(interfaceManager * inst , int bid);
MATHLIBRARY_API bool STACKMODE bert_connect(interfaceManager * inst, std::string IP);
These are the functions that I am trying to export and that are considered unresolved external symbols
EDIT
I tried to use the VS developer tools using dumpbin /EXPORTS MultiSite.lib and all my functions are there

The header doesn't contain the magic line needed to make Visual Studio link the right library. That's #pragma comment(lib, "MultiSite.lib"). It goes after #define MATHLIBRARY_API extern "C" __declspec(dllimport).
Alternatively, you can indeed tell the linker directly that MultiSite.lib is an additional input. See the Visual Studio linker property pages of your executable project.

"What I did in the independent project is to add the library to the Linker > Input > Additional Dependencies and add the header directories"
As far as I'm concerned, the project lacks MultiSite.lib. I suggest you should add the path to the .lib file to the Additional Library Directories (property -> linker -> General -> Additional Library Directories).

The problem was using a 64-bit library on a 32-bit application.
That's why it was working fine when I added it to the same solution but not in my independent project.
I used to think that visual studio can detect a wrong format but turns out that just the exported symbol's names change between two same libraries with different bit configuration.
Hence this explains the unresolved external symbol error that I encountered

Related

Linker can't find LIB file of the DLL imported

I've looked through full 14 pages list of similar problems but didn't find my case.
I have VS2017 c++ solution which has two projects DLL and EXE. EXE projects includes DLL header to import function from it.
The problem is that linker can't find dllproject.lib file. I tried to add it to Linker -> Input -> Additional Dependencies but didn't help because linker failed to find that lib file and it exists in the output folder.
Then I used
#pragma comment( lib, "C:\\FULL_PATH\\dllproject.lib")
And this time helped. But the problem is my local absolute path to the lib. I suppose I can somehow configure that in the project settings, but all my attempts failed.
In the DLL header file I have the block (was advised in other answers).
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif
Please help.
Adding a library to your project is a two step process.
You add the library name to Linker/Input/Additional Dependencies and you add the library folder to Linker/General/Additional Library Directories.
Then of course you have the potential problem of your program failing to find your DLL, but that's another question.

VS 2015 compiler can't see a C variable

I'm writing a c++ project with MS Visual Studio 2015. In my project I have to call some variables declared and defined in a C file.
As you can see below, the variables are enclosed within the extern "C" structure:
#if defined __cplusplus
extern "C" {
#endif
GainType MYDLL_API BestCost; /* Cost of the tour in BestTour */
int MYDLL_API *BestTour; /* Table containing best tour found */
double MYDLL_API LowerBound; /* Lower bound found by the ascent */
#if defined __cplusplus
}
#endif
But, however, the compiler isn't able to resolve these three variables.
I've searched everywhere, i've tried all the proposed solutions, but it still doesn't work.
How can I solve it?
Thanks to everybody!
This looks like the c code is in a DLL
For the compiler to find this.
Need to define MYDLL_API as __declspec(dllimport) for C++
Need to link with .lib file
Seems that the symbols come from a DLL library. Then you need to add the import library (*.lib) of the DLL to the list of libraries the application is linked with.
In Visual Studio options, this can be done under project properties, Linker / Input / Additional Dependencies (add the lib name there).
Also make sure that the path to the *.lib is set in Linker / General / Additional Library Directories.

Using a class inside a dll

I have a class inside a dll which I want to use in another project. I read this tutorial about how to do this and my pseudo code looks like this
interface.h
#ifdef EXPORT
#define SOMEAPI __declspec(dllexport)
#else
#define SOMEAPI __declspec(dllimport)
#endif
struct ISomeInterface
{
virtual void SomeMethod()=0;
};
typedef ISomeInterface* SOMEHANDLE;
#define EXTERN_C extern "C"
EXTERN_C SOMEAPI SOMEHANDLE WINAPI CreateSomething(VOID);
And then I have SomeDLL.dll which implements ISomeInterface and CreateSomething.
When I try to use this in my client I get linker error. The client looks like this:
Client.cpp
#include "interface.h"
SOMEHANDLE h = ::CreateSomething(); // Linker error here: Unresolved external
I can solve this by adding the dll project as a dependency of Client project in VC++. Then everything is good.
The problem is what if I want to use this a standalong dll(which is the case right now)? How do I get rid of the linker error then?
I can solve this by adding the dll project as a dependency of Client project
Yes, that automatically does the one thing you have to do in a stand-alone project by hand. Project + Properties, Linker, Input, Additional Dependencies setting. Add the .lib file that was generated by the DLL project. The import library, it tells the linker about the functions exported by the DLL.

Create a DLL in C and link it from a C++ project

As per title, I'm trying to build a DLL using C and link it from a C++ project. I read and followed different tutorials on internet but everytime there is something missing and I don't understand what.
Here's what I did, step by step:
I created a new Win32 project, named testlib, then, from the wizard, I chose "DLL" and "Empty project".
Added a header:
//testlib.h
#include <stdio.h>
__declspec(dllexport) void hello();
Added a source; since I want it to be a C source I read I should simplly rename the .cpp file in .c, so
//testlib.c
#include "testlib.h"
void hello() {
printf("DLL hello() called\n");
}
Build succeded.
Now I would like to use my useful dll in another project.
Then: new project (testlibUse). This time I selected "Empty project".
No need to add an header, just created a cpp source
//main.cpp
#include <testlib.h>
int main() {
hello();
}
Then:
I added the path to the folder where is testlib.dll in Properties->VC++ directories->Executable directories
I added the path to the folder where is testlib.h in Properties->VC++ directories->Include directories
I added the path to testlib.lib (included extension) in Properties->Linker->Input->Additional dependencies
I tried to build but I got a linker error:
LINK : C:\path\testlibUse\Debug\testlibUse.exe not found or not built by the last incremental link; performing full link
main.obj : error LNK2019: unresolved external symbol "void __cdecl hello(void)" (?hello##YAXXZ) referenced in function _main
C:\path\testlibUse\Debug\testlibUse.exe : fatal error LNK1120: 1 unresolved externals
If I go back to testlib, rename back testlib.c in testlib.cpp and rebuild the dll, then I am able to build testlibUse but I get a "dll not found" error at runtime.
I tried also to change the configurations of both projects in "Release" (changing the path where needed), but nothing changed.
Sorry for the long post but I think it was necessary to write down exactly what I did.
Any suggestions?
Besides, are there any configuration parameters I need to change if I want to use my dll in a Qt project?
You have several problems:
The header file should mark the functions as exported when being compiled in the DLL but imported when being compiled by a library user.
The header file should wrap the function declarations in an extern "C" block when being compiled as C++ to ensure that the names do not get mangled
The DLL is not on your executable's library search path, so it can't be found at runtime.
To fix (1) and (2), rewrite your header like this:
#ifdef __cplusplus
extern "C" {
#endif
// Assume this symbol is only defined by your DLL project, so we can either
// export or import the symbols as appropriate
#if COMPILING_MY_TEST_DLL
#define TESTLIB_EXPORT __declspec(dllexport)
#else
#define TESTLIB_EXPORT __declspec(dllimport)
#endif
TESTLIB_EXPORT void hello();
// ... more function declarations, marked with TESTLIB_EXPORT
#ifdef __cplusplus
}
#endif
To fix (3), copy the DLL into the same folder as your executable file. The "executable directories" setting you're setting doesn't affect DLL searching -- see MSDN for a detailed description of how DLLs are searched for. The best solution for you is to copy your DLL into the directory where your executable file lives. You can either do this manually, or add a post-build step to your project that does this for you.
You should extern "C" the include:
extern "C" {
#include <testlib.h>
}
It looks as if you need to make sure the compiler not mangle the symbol name in the cpp build. You should be able to add an extern "C" to the definition in testlib.h:
#ifdef __cplusplus
extern "C"
#endif
__declspec(dllexport) void hello();
Here's a method for your C header file that could be included by C++. Make sure to set TESTLIB_EXPORTS only in your DLL preprocessor settings. In projects that include this header to use the DLL, the header will declare the functions as imports instead of exports.
The __cplusplus guard will tell the compiler to import your functions using C name decoration instead of C++ name decoration.
#include <stdio.h>
#ifdef TESTLIB_EXPORTS
#define TESTLIB_API __declspec(dllexport)
#else
#define TESTLIB_API __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
TESTLIB_API void hello();
/* other prototypes here */
#ifdef __cplusplus
}
#endif

Visual C++ "List of Libraries" meaning

I'm trying to compile a c++ source code file from the DXC competition.
The instructions are:
To compile any of the C++ examples (or a DA written in C++) under Windows, MS
Visual C++ 8.0 (2005) is required. Make sure to add %DXC_HOME%\Lib and
%DXC_HOME%\Include to your library and header search paths respectively, and add
dxcApi.lib to your list of libraries (or dxcApid.lib if compiling in debug
mode).
I added Lib and the Include libraries to the library and search paths and it imported them. What I didn't understand is the meaning of the second step: "add dxcApi.lib to your list of libraries" - what does it mean?
Without this step I'm getting linker errors, such as:
Error 1 error LNK2019: unresolved external symbol
"__declspec(dllimport) public: _thiscall
Dxc::CandidateSet::~CandidateSet(void)"
(_imp_??1CandidateSet#Dxc##QAE#XZ) referenced in function "public:
void __thiscall ExampleDA::sendDiagnosis(void)"
(?sendDiagnosis#ExampleDA##QAEXXZ) D:\Dropbox\Work\Visual Studio
2010\Projects\DXC11\DXC11\ExampleDA.obj DXC11
I'm stuck with this problem for quite some time now and I'm desperate for help!
Thanks a lot
You need to add the specific lib file to the libraries list, so that the linker can search it for the symbols you're missing.
The task says to add that particular .lib to the list of libraries that get linked to your code. Without saying that this library should be linked, the implementation for the functions defined in its headers is not available to the linker and you get that unresolved external symbol.
In VS, you can add something to the linked libraries list either through a #pragma comment or in the project settings:
// at the top of main.cpp, preferrably
#pragma comment(lib, "the_lib_name.lib") // .lib optional
You can have different libraries for debug and release with simply surrounding the #pragma comment in an #if block:
#ifdef NDEBUG // release
#pragma comment(lib, "the_lib_name.lib")
#else // debug
#pragma comment(lib, "the_lib_named.lib") // most debug libraries end with a 'd'
#endif
And for the project settings you can do so with
[Project] -> <Project Name> Properties (or Alt-F7) -> Configuration Properties
-> Linker -> Input -> Additional Dependencies
Just add the_lib_name.lib at the front (followed by either a space or a semi-colon ;). Make sure you add the correct library for the active project configuration (debug / release).