complie dll but appear error LNK2019 - c++

I implement a C++ function as DLL with vs2013. But I have linker error (error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup) building to the dll. I have proper setup and not sure what is wrong. The code is very simple, but I don't know why it can't be built successfully.
Demoone.h
#ifndef _Demo_H_
#define _Demo_H_
#ifdef LIBDLL
#define LIBDLL extern "C" _declspec(dllimport)
#else
#define LIBDLL extern "C" _declspec(dllexport)
#endif
LIBDLL int Add(int plus1, int plus2);
#endif
Demoone.cpp
#include "Demoone.h"
int Add(int a, int b)
{
return (a + b);
}
update:
I modified the header file as bellow
#ifndef _Demo_H_
#define _Demo_H_
extern "C" int Add (int a , int b);
#endif
and add an def file
LIBRARY "Dllmaketwo"
EXPORTS
Add # 1
The same linker error (error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup) also appeared.

If you want to use load-time linking in the project that uses the DLL you need to link against the .lib produced by the DLL project build.
You can do that with:
#pragma comment(lib, "dllproject.lib")
Or by adding the .lib to the additional dependencies line in the project settings under Linker->Input. You may also need to mess with the library search path, either in the VC++ Directories page or in the Linker->General page.

#ifndef _Demo_H_
#define _Demo_H_
#ifdef LIBDLLIMPORT //Changed here
#define LIBDLL extern "C" _declspec(dllimport)
#else
#define LIBDLL extern "C" _declspec(dllexport)
#endif
LIBDLL int Add(int plus1, int plus2);
#endif
You should not use a same name in #ifdef and #define,
Did you setup you project correctly? And you should not write a `main()' function in it.

Related

C++ dll and name mangling issue

I am trying out a simple test DLL project. Under my solution, I have two projects - first C++ Dll (library) and second C++ exe (driver). Below I've attached a snapshot of the basic project setup:
dllmain.h
#ifndef DLLMAIN_H_
#define DLLMAIN_H_
#ifdef FFMPEGLIB_EXPORTS
#define FFMPEGLIB_API __declspec(dllexport)
#else
#define FFMPEGLIB_API __declspec(dllimport)
#endif // FFMPEGLIB_EXPORTS
static void TestFoo();
extern "C" FFMPEGLIB_API void Test(int* num);
extern "C" FFMPEGLIB_API void ProxyFoo();
#endif
dllmain.cpp
#include "dllmain.h"
#include "A.h"
void TestFoo()
{
A a;
a.foo();
}
void Test(int* num)
{
*num = *num + 1;
}
void ProxyFoo()
{
TestFoo();
}
driver.cpp
#include <iostream>
#include "dllmain.h"
int main(int argc, char** argv)
{
int mum = 4;
Test(&num);
std::cout << num;
ProxyFoo();
return 0;
}
The library project compiles normally, but the exe fails to compile with a linker error:
Code Description Project File
LNK2001 unresolved extern symbol _imp_ProxyFoo driver driver.obj
LNK2001 unresolved extern symbol _imp_Test driver driver.obj
LNK1120 2 unresolved externals driver driver.exe
I have two questions here:
Why does the function name of dllmain.h get mangled in spite of being marked as extern "C"?
Why can I not create an instance of test class A from extern methods? What would be a good way of doing that?
Why the function name of dllmain.h getting mangled in spite being
marked as extern "C"?
Because __declspec(dllimport).
Why can I not create instance of test class A from extern methods?
What would be good way of doing it?
I think that's fine, but you didn't provide any class A code. Just do this:
class __declspec(dllexport) A
{
/* ... */
};
Why EXE compile failed?
This is because you have not imported the LIB file of the DLL into the project.
There are two ways to import it:
Add #program comment(lib, "<YOUR_LIB_FILE>.lib") to the code file.
Add <YOUR_LIB_FILE>.lib to Properties -> Linker -> Input -> Additional Dependencies.
Microsoft documentation: https://learn.microsoft.com/en-us/cpp/build/importing-and-exporting
You need to put the extern "C" thing around your function definitions that you intend to export in dllmain.cpp so it matches the linkage of your declaration.
Also, you need to do the declexport thing too.
extern "C"
{
__declspec(dllexport) void Test(int* num)
{
*num = *num + 1;
}
__declspec(dllexport) void ProxyFoo()
{
TestFoo();
}
}

error resolving external symbol

I am trying to create a simple c++ project in Visual studio 2015
Peakdetector.h
#ifndef PEAKDETECTOR_H
#define PEAKDETECTOR_H
//-------------------------------------------------------
#ifdef DLL_BUILD_SETUP
#ifdef Q_OS_LINUX
#define DLLSPEC __attribute__((visibility("default")))
#else
#define DLLSPEC __declspec(dllexport)
#endif
#else
#ifdef Q_OS_LINUX
#define DLLSPEC
#else
#define DLLSPEC __declspec(dllimport)
#endif
#endif
namespace vpg {
#ifndef VPG_BUILD_FROM_SOURCE
class DLLSPEC PeakDetector
#else
class PeakDetector
#endif
private:
int __seek(int d) const;
double __getDuration(int start, int stop);
}
inline int PeakDetector::__seek(int d) const
{
return ((m_intervalslength + (d % m_intervalslength)) % m_intervalslength);
}
#endif
PeakDetector.cpp
#include "stdafx.h"
#include "peakdetector.h"
namespace vpg {
void PeakDetector::__updateInterval(double _duration)
{
//other stuff
}
}
When I try to run this application i get error
LNK2019 unresolved external symbol "__declspec(dllimport) private: int __cdecl vpg::PeakDetector::__seek(int)const " (__imp_?__seek#PeakDetector#vpg##AEBAHH#Z) referenced in function "private: void __cdecl vpg::PeakDetector::__updateInterval(double)" (?__updateInterval#PeakDetector#vpg##AEAAXN#Z) MyCustomProject
I am new to this and cannot figure out why am I having this error.I have just copy pasted this code from an example.Please let me know if I am missing any code. Also I dont have any .lib files.
You must add the DLL_BUILD_SETUP the defines in Visual Studio.
In order to do that, yo must go to
Project Settings -> C/C++ -> Preprocessor -> Preprocessor definitions
and add the definition to the list.
You must use the spec __declspec(dllexport) when compiling the library that is exporting the symbols (in this case the class), and __declspec(dllimport) in the project that USES that library.
I see from the source code that you've provided that there is an additional definition VPG_BUILD_FROM_SOURCE which disables the export in order to using static/inline linking, you may try to add that define instead.

How to export class constructor in c++ DLL project?

I'm building a dll project in Visual Studio 2013. My header file for class definition is as follows:
#ifndef PREPROCESSOR_H
#define PREPROCESSOR_H
#ifndef MAKEDLL
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __declspec(dllimport)
#endif
#include "common.h"
class DLLEXPORT Preprocessor
{
public:
Preprocessor();
...
private:
...
};
After building it, I called this class from another project. I've included its header file, generated dll and .lib files. But I got a LNK2001 error for my main.obj file:
error LNK2001: unresolved external symbol "public: __cdecl Preprocessor::Preprocessor (void)" (??0Preprocessor##QEAA#XZ
What did I wrong here?? Thank you.

LNK2019 unresolved external appears when function is used inside static method

I have a C++ Visual Studio 2013 console application which is supposed to make use of a DLL MyDLLlib.dll which I have written. MyDLLlib is written in C. One of the functions is called Get_Version. The prototype is
const char *Get_Version();
I put this at the top of the source files to make use of the prototype:
extern "C"{
#include "MyDLLlib.h"
}
If in the function is called in the main as this
printf("version %s\n",Get_Version());
then it works.
However if I add a class with some static methods and a static method makes a call to Get_Version()
const char * ret = Get_Version();
then I get a link error:
Error 1 error LNK2019: unresolved external symbol
"__declspec(dllimport) char * __cdecl Get_Version(void)" (__imp_?Get_Version##YAPADXZ)
referenced in function "private: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl ServiceDispatch::decoder_Get_Version(class StringBuffer &)"
(?decoder_Get_Version#ServiceDispatch##CA?AV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##AAVStringBuffer###Z)
D:\devt\CplusPlus\VSTrials\Link_to_MyDLLlib\Link_to_MyDllLib\ServiceDispatch.obj Link_to_MyDLLlib``
I am using the same include.
Any clue as to what I might be doing wrong?
If you have CLASS_DECLSPEC defined always as __declspec(dllimport), this will not work for sure. Look at this sample:
DLL_header.h
#if defined( _BUILD_DLL )
# define DLLAPI __declspec(dllexport) //Export when building DLL
#else
# define DLLAPI __declspec(dllimport) //Import when using in other project
#endif
DLLAPI const char *Get_Version();
DLL_source.cpp
#include "Header.h"
const char *Get_Version()
{
return "1.1.0.4";
}
Build DLL with _BUILD_DLL defined.
Main.cpp
#include "DLL_header.h"
int main()
{
printf("%s\n", Get_Version());
return 0;
}
Build this, with _BUILD_DLL not defined.
In your case, it could be problem with extern "C" - you include header inside extern "C", which declares Get_Version() as having __cdecl linkage. But linker is searching for
__imp_?Get_Version##YAPADXZ
Which is a mangled (C++) name. Is your DLL a C or C++ project? If your DLL is build as C project (not C++), put extern "C" on Get_Version()'s declaration with this #ifdef:
#ifdef __cplusplus
extern "C" {
#endif
DLLAPI const char *Get_Version();
#ifdef __cplusplus
}
#endif
Either way, remove extern "C" from around the #include. Also, check if .lib file for this DLL is attached to project as dependency.

implicit linking DLL question

I started studying DLL's with implicit linking. I don't really fully understand how it works. Please correct me where I'm wrong.
I failed to compile the next code(3 modules):
MyLib.h
#ifdef MYLIBAPI
#else
#define MYLIBAPI extern "C" __declspec(dllimport)
#endif
MYLIBAPI int g_nResult;
MYLIBAPI int Add(int nLeft, int nRight);
As far as I understand this is the header of the DLL. #define MYLIBAPI extern "C" __declspec(dllimport) means that here we are going to declare some functions/variables that will be described in devoted .cpp file and will be contained in a DLL.
MyLibFile1.cpp
#include <windows.h>
#define MYLIBAPI extern "C" __declspec(dllexport)
#include "MyLib.h"
int g_nResult;
int Add(int nLeft, int nRight) {
g_nResult = nLeft + nRight;
return(g_nResult);
}
So, this is obviously the file where our functions are implemented. This is the part of the DLL, right?
MyExeFile1.cpp
#include <windows.h>
#include <strsafe.h>
#include <stdlib.h>
#include "MyLib.h"
int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int) {
int nLeft = 10, nRight = 25;
TCHAR sz[100];
StringCchPrintf(sz, _countof(sz), TEXT("%d + %d = %d"),
nLeft, nRight, Add(nLeft, nRight));
MessageBox(NULL, sz, TEXT("Calculation"), MB_OK);
StringCchPrintf(sz, _countof(sz),
TEXT("The result from the last Add is: %d"), g_nResult);
MessageBox(NULL, sz, TEXT("Last Result"), MB_OK);
return(0);
}
So, this is the executable file where we use the functions from the library.
The whole thing doesn't work. I tried to put this all into one directory and compile at once. I tried first to compile a DLL from the first two modules(successfully) and then compile the executable (changing the path to the header file). However it resulted in 2 errors both times:
error LNK2019: unresolved external symbol _WinMain#16 referenced in function ___tmainCRTStartup
\Visual Studio 2008\Projects\MyExeFile1\Debug\MyExeFile1.exe : fatal error LNK1120: 1 unresolved externals
What' s the correct way to do that - what should I change in the code and how should I compile the code (I use VS2008)?
Thanks.
#include <tchar.h> to solve the linker error.
Your header file should look like this:
#ifdef BUILDING_DLL
# define MYLIBAPI extern "C" __declspec(dllexport)
#else
# define MYLIBAPI extern "C" __declspec(dllimport)
#endif
MYLIBAPI int __stdcall Add(int nLeft, int nRight);
Right-click your DLL project in Solution Explorer, Properties, C/C++, Preprocessor, Preprocessor Definitions, add "BUILDING_DLL". Repeat for the Release configuration.
You can verify that your DLL properly exports the functions with Dumpbin.exe /exports.
The __declspec(dllimport) declarator is not strictly necessary, it does however make it more efficient. The __stdcall attribute is not necessary either, it does however make your DLL usuable from any language that supports calling DLL exports.
Change _tWinMain to WinMain in MyExeFile1.cpp. It is looking for your entry point to be named WinMain not _tWinMain and so the linker is complaining that it can't find WinMain.
There are project settings that determine what name the entry point function should be, but I'm not sure which one would require _tWinMain.
Edit
According to this posting, _tWinMain is a define that maps to WinMain if you include tchar.h.link text
Does it even compile? Shouldn't you #include <tchar.h> for all TCHAR types and definitions to work?