Unresolved external calling C function from C++ [duplicate] - c++

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
I have a Visual Studio solution which has to call legacy C code from C++ code and I am getting linker errors. Eg:
1>------ Build started: Project: testapp_soln, Configuration: Debug Win32 ------
1>legacy.lib(launchit.obj) : error LNK2019: unresolved external symbol "void __cdecl legacy_task(void)" (?legacy_task##YAXXZ) referenced in function "public: virtual void __thiscall Launchit::DoIt(void)" (?DoIt#Launchit##UAEXXZ)
1>E:\share\code\so\TestApp\testapp_soln\Debug\testapp_soln.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I have a static lib project called legacy with a C++ class, launchit calling the C functions in legacy C code.
Here are details of the legacy project.
legacy.h:
#ifndef LEGACY_H_
#define LEGACY_H_
extern void legacy_task (void);
extern int initialise_thing();
#endif /* LEGACY_H_ */
legacy.c
#include "legacy.h"
void legacy_task (void)
{
/* doing things */
initialise_thing();
}
legacy_init.c
#include <stdio.h>
int initialise_thing()
{
printf("Doing init thing here\n");
return 0;
}
legacy C stuff called from launchit class
launchit.hpp
#ifndef LAUNCHIT_HPP_
#define LAUNCHIT_HPP_
class Launchit
{
public:
Launchit();
virtual ~Launchit();
virtual void DoIt();
};
#endif // LAUNCHIT_HPP_
launchit.cpp
#include "Launchit.hpp"
#include "legacy.h"
Launchit::Launchit()
{
}
Launchit::~Launchit()
{
}
void Launchit::DoIt()
{
legacy_task();
}
Then I build this as a static lib. It build just fine.
I have a console application project like this:
#include "launchit.hpp"
int main() {
Launchit li;
li.DoIt();
}
But this gives me linker error:
legacy.lib(launchit.obj) : error LNK2019: unresolved external symbol "void __cdecl legacy_task(void)" (?legacy_task##YAXXZ) referenced in function "public: virtual void __thiscall Launchit::DoIt(void)" (?DoIt#Launchit##UAEXXZ)
How can I fix this linker error?

Notice that the link error says that the symbol ?legacy_task##YAXXZ was not found. This is a mingled name, derived by the C++ compiler from the function name. For compatibility with C, you need to use "extern "C" in legacy.h:
#ifdef __cplusplus
extern "C" {
#endif
void legacy_task (void);
#ifdef __cplusplus
}
#endif
This way, the compiler does not mangle the funtion's name.
For a detailed discussion of extern "C", see In C++ source, what is the effect of extern "C"?

Related

Errors LNK 2019 and LNK2028 for one function in a class, other works fine

I normally work in c# and am out of my wits for this one . I used Walkthrough: Creating and Using a Dynamic Link Library (C++) to create a Dynamic Link Library.
I have defined two methods as shown below
DeveloperConsoleManager.h
#pragma once
#include "atlstr.h"
#ifdef DEVCONSOLEMANAGER_EXPORTS
#define DEVCONSOLEMANAGER_API __declspec(dllexport)
#else
#define DEVCONSOLEMANAGER_API __declspec(dllimport)
#endif
namespace DeveloperConsoleManager
{
class DeveloperConsoleLogic
{
public:
// Returns a + b
static DEVCONSOLEMANAGER_API double Add(double a, double b);
static DEVCONSOLEMANAGER_API bool CheckforValidFile(CString fileName);
};
}
DeveloperConsoleManager.cpp
// DeveloperConsoleManager.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "DeveloperConsoleManager.h"
namespace DeveloperConsoleManager
{
double DeveloperConsoleLogic::Add(double a, double b)
{
return a + b;
}
bool DeveloperConsoleLogic :: CheckforValidFile(CString fileName)
{
return false;
}
}
I use these methods in a .cpp file in a different project (type: Application (.exe)). When I Build the solution, there are following linker errors
Warning 1 warning C4273: 'DeveloperConsoleManager::DeveloperConsoleLogic::Add' : inconsistent dll linkage e:\md_69\developerconsolemanager\developerconsolemanager.cpp 10
Warning 2 warning C4273: 'DeveloperConsoleManager::DeveloperConsoleLogic::CheckforValidFile' : inconsistent dll linkage e:\md_69\developerconsolemanager\developerconsolemanager.cpp 16
Error 3 error LNK2028: unresolved token (0A0004F1) "public: static bool __cdecl DeveloperConsoleManager::DeveloperConsoleLogic::CheckforValidFile(class ATL::CStringT > >)" (?CheckforValidFile#DeveloperConsoleLogic#DeveloperConsoleManager##$$FSA_NV?$CStringT#_WV?$StrTraitMFC_DLL#_WV?$ChTraitsCRT#_W#ATL#####ATL###Z) referenced in function "public: void __thiscall CSaSsiConsoleUi::UploadSsiCheck(void)" (?UploadSsiCheck#CSaSsiConsoleUi##$$FQAEXXZ) E:\MD_69\DeveloperConsoleUI\SaSsiConsoleUI.obj
Error 4 error LNK2019: unresolved external symbol "public: static bool __cdecl DeveloperConsoleManager::DeveloperConsoleLogic::CheckforValidFile(class ATL::CStringT > >)" (?CheckforValidFile#DeveloperConsoleLogic#DeveloperConsoleManager##$$FSA_NV?$CStringT#_WV?$StrTraitMFC_DLL#_WV?$ChTraitsCRT#_W#ATL#####ATL###Z) referenced in function "public: void __thiscall CSaSsiConsoleUi::UploadSsiCheck(void)" (?UploadSsiCheck#CSaSsiConsoleUi##$$FQAEXXZ) E:\MD_69\DeveloperConsoleUI\SaSsiConsoleUI.obj
Error 5 error LNK1120: 2 unresolved externals E:\MD_69\Debug\DeveloperConsoleUi.exe
There is no linker error for the "Add" method.
I have already included "DeveloperConsoleManager.lib" in Linker -> Input -> Additional Dependencies. Please help me find out what exactly am I doing wrong.
I would be glad to add any additional information needed.
Thanks to #Igor Tandetnik and the awesome thing that is internet, I figured it out. I am adding it as an answer so that some one else might benefit.
The problem was with CString. The project in which the function was defined was a dynamic link library (dll) and the call was being made from an MFC application. Now, the issue was that, MFC uses for CString while the non-MFC dll uses .
CString in is defined as:
typedef ATL::CStringT< TCHAR, StrTraitMFC_DLL< TCHAR > > CString;
while in is defined as:
typedef CStringT< TCHAR, StrTraitATL< TCHAR > > CString;
This, as you can clearly see is different. The workaround I used was using CAtlString instead of CString . However, please feel free to suggest any better way if you come across.

C++ DLL: unresolved external symbol

I seem to have some issues with creating new files for my project.
The issue is that in my sk_error.h file it seems to complain about unresolved external symbols (full error report below). When I place my OutOfRange class in my sk_interface.h file no one complains but when I put the class in the errors file it has issues with it.
If I was to comment out OutOfRange it works perfectly fine so I dont think that it is an issue with the DLL setup.
sk_error.h
#include <sk_platform.h>
#include <sk_interface.h>
namespace sky {
class SK_API OutOfRange : IError {
public:
OutOfRange() {
m_message = " Out Of Range";
m_value = (0 << 1);
}
std::string getMessage() override {
return m_message;
}
};
}
sk_platform.h
#if defined (SK_NONCLIENT_BUILD)
#ifndef SK_API
#define SK_API __declspec(dllexport)
#endif
#else
#ifndef SK_API
#define SK_API __declspec(dllimport)
#endif
#endif
sk_interface.h
#include <sk_platform.h>
#include <string>
namespace sky {
...
class SK_API IError {
public:
virtual std::string getMessage() = 0;
protected:
uint32_t m_value = 0;
std::string m_message = "Error not initialized";
};
}
The Client Project using the DLL
#include <sk_logmanager.h>
#include <sk_error.h>
#include <iostream>
int main() {
sky::g_LogManager.startup();
sky::OutOfRange err;
std::cout << err.getMessage() << "\n";
sky::g_LogManager.shutdown();
while (1) {}
}
Error Output
1>------ Build started: Project: SkyTest, Configuration: Debug Win32 ------
1>main.cpp
1>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall sky::OutOfRange::OutOfRange(void)" (__imp_??0OutOfRange#sky##QAE#XZ) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall sky::OutOfRange::getMessage(void)" (__imp_?getMessage#OutOfRange#sky##UAE?AV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##XZ) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall sky::OutOfRange::~OutOfRange(void)" (__imp_??1OutOfRange#sky##QAE#XZ) referenced in function _main
1>C:\Users\Matt\Documents\Game Development\DevEnv\SkyTest\Debug\SkyTest.exe : fatal error LNK1120: 3 unresolved externals
1>Done building project "SkyTest.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Edit:
I am using Visual Studio 2017 (could be the source of the error). The Client Project is using the .lib file.
An unresolved external is always a link error. It even has it in its name: LNK2019.
It is telling you it cannot find the implementation for sky::OutOfRange::OutOfRange()
You have it in a header somewhere and you've called it, but you have not linked to the library that implements it.
We have no way of telling you what library implements it or where it lives on your hard drive. You will have to consult the documentation for OutOfRange, the author of it, or yourself.
I can tell you that you will want to check:
right click the executable project->
properties->linker->general->additional library directories
properties->linker->input->additional dependencies
and make sure the path to the library that defines OutOfRange is in the former and the library name is in the latter.
EDIT: If the library itself has a header that imports it, as it appears from the code you posted, you just need to set up the additional directories part.
In the end, you have to consult the documentation for whatever library you are using or hit up their forums.
I am not sure but this may be related to your solution configuration and solution platform. It wasn't working for me, when I set my solution configuration to "Debug" and platform to "x64"; it started working after setting it to Release - x86

C++ Unresolved Externals because of header [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 8 years ago.
I just started with C++ for some OpenGL applications and wanted to pack some monster functions into a util class so that my code remains clean. This is what I did:
awesomeClass.h :
#pragma once
class AwesomeClass
{
public:
static void do_something_awesome();
};
awesomeClass.cpp :
#include "awesomeClass.h"
void do_something_awesome(){
//...
}
main.cpp :
#include "awesomeClass.h"
int main(int argc, char** argv)
{
AwesomeClass::versuchen();
return 0;
}
Output:
Error 3 error LNK1120: 1 unresolved externals \Visual Studio 2013\Projects\TestEnvironmment\Debug\TestEnvironmment.exe TestEnvironmment
Error 2 error LNK2019: unresolved external symbol "public: static void __cdecl AwesomeClass::do_something_awesome(void)" (?do_something_awesome#AwesomeClass##SAXXZ) referenced in function _SDL_main \Visual Studio 2013\Projects\TestEnvironmment\TestEnvironmment\main.obj TestEnvironmment
What is wrong with that code? I mean it works when I paste everything in one file.
You should write
void AwesomeClass::do_something_awesome(){... }
Instead of
void do_something_awesome(){... }
Otherwise the function you implement does not belong to the class.
You should write this if you want write do_something_awesome in separate cpp file.
void AwesomeClass::do_something_awesome(){
//...
}
Or you can use:
#pragma once
class AwesomeClass
{
public:
static void do_something_awesome(){
//code here
}
};

Link error when referencing managed dll to native c++

I am trying to create a rather simple project in native c++ that calls a a managed dll.
this how my native c++ code looks:
// MyCppStud.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "MyStudWrapper\MyStudentWrapperWrapper.h"
int _tmain(int argc, _TCHAR* argv[])
{
char * path = "C:/Users/rami.schreiber/documents/visual studio 2013/Projects/TestProj/test.xml";
MyStudentWrapperWrapper* student = new MyStudentWrapperWrapper();
// student->GetStudent(path);
return 0;
}
and here are the .h and .cpp files for the managed dll (compiled with /clr)
//MyStudentWrapperWrapper.h
#pragma once
//#ifdef THISDLL_EXPORTS
#define THISDLL_API __declspec(dllexport)
/*#else
#define THISDLL_API __declspec(dllimport)
#endif*/
class MyStudentWrapper;
class THISDLL_API MyStudentWrapperWrapper
{
private:
MyStudentWrapper* _Impl;
public:
MyStudentWrapperWrapper();
MyStudentWrapperWrapper(MyStudentWrapper* student);
~MyStudentWrapperWrapper();
MyStudentWrapperWrapper* GetStudent(const char* path);
void SaveStudent(MyStudentWrapperWrapper* student, const char* path);
};
// MyStudentWrapperWrapper.cpp
#pragma once
#include "stdafx.h"
#include "MyStudWrapper.h"
#include "MyStudentWrapperWrapper.h"
MyStudentWrapperWrapper::MyStudentWrapperWrapper()
{
_Impl = new MyStudentWrapper;
}
when i build the solution i get a link error
1>MyCppStud.obj : error LNK2019: unresolved external symbol "public: __thiscall MyStudentWrapperWrapper::MyStudentWrapperWrapper(void)" (??0MyStudentWrapperWrapper##QAE#XZ) referenced in function _main
1>c:\users\...\documents\visual studio 2013\Projects\MyStudentProj\Debug\MyCppStud.exe : fatal error LNK1120: 1 unresolved externals
From what I understand I am not referencing the the .lib file correctly and therefor the linker does not recognize the c'tor for my wrapper class.
can someone please explain how to correctly reference the dll to my c++ project.
thank you very much!

C++ LNK2019 error with constructors and destructors in derived classes

I have two classes, one inherited from the other. When I compile, I get the following errors:
Entity.obj : error LNK2019: unresolved external symbol "public: __thiscall Utility::Parsables::Base::Base(void)" (??0Base#Parsables#Utility##QAE#XZ) referenced in function "public: __thiscall Utility::Parsables::Entity::Entity(void)" (??0Entity#Parsables#Utility##QAE#XZ)
Entity.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall Utility::Parsables::Base::~Base(void)" (??1Base#Parsables#Utility##UAE#XZ) referenced in function "public: virtual __thiscall Utility::Parsables::Entity::~Entity(void)" (??1Entity#Parsables#Utility##UAE#XZ)
D:\Programming\Projects\Caffeine\Debug\Caffeine.exe : fatal error LNK1120: 2 unresolved externals
I really can't figure out what's going on.. can anyone see what I'm doing wrong? I'm using Visual C++ Express 2008. Here are the files..
"include/Utility/Parsables/Base.hpp"
#ifndef CAFFEINE_UTILITY_PARSABLES_BASE_HPP
#define CAFFEINE_UTILITY_PARSABLES_BASE_HPP
namespace Utility
{
namespace Parsables
{
class Base
{
public:
Base( void );
virtual ~Base( void );
};
}
}
#endif //CAFFEINE_UTILITY_PARSABLES_BASE_HPP
"src/Utility/Parsables/Base.cpp"
#include "Utility/Parsables/Base.hpp"
namespace Utility
{
namespace Parsables
{
Base::Base( void )
{
}
Base::~Base( void )
{
}
}
}
"include/Utility/Parsables/Entity.hpp"
#ifndef CAFFEINE_UTILITY_PARSABLES_ENTITY_HPP
#define CAFFEINE_UTILITY_PARSABLES_ENTITY_HPP
#include "Utility/Parsables/Base.hpp"
namespace Utility
{
namespace Parsables
{
class Entity : public Base
{
public:
Entity( void );
virtual ~Entity( void );
};
}
}
#endif //CAFFEINE_UTILITY_PARSABLES_ENTITY_HPP
"src/Utility/Parsables/Entity.cpp"
#include "Utility/Parsables/Entity.hpp"
namespace Utility
{
namespace Parsables
{
Entity::Entity( void )
{
}
Entity::~Entity( void )
{
}
}
}
The relevant bit is this:
unresolved external symbol "public: __thiscall Utility::Parsables::Base::Base(void)"
You need to provide a definition for Base::Base and Base::~Base. A declaration is not good enough. Even if you have nothing to do in either function, you need to leave an empty function body, because C++ actually requires the function to exist. C++ puts things like virtual table maintenance inside your constructors and destructors, so they must be defined even if you don't need to do anything there -- C++ has to do things in there.
Are you sure Base.cpp is being included in the build?
Just encountered this exact same error today in Visual Studio 2015. Unfortunately the accepted answer didn't worked (as well as answers from many same questions). The thing that worked for me was right click on the base class cpp file, exclude and then include it again. I think somehow VS got confused while moving file around and renames and it just silently refused to compile it even though it was marked as "Included In project" = true in property editor as well as listed in vcproj file in group. This is horrible error and ended up spending good hour on it.
Either your base.cpp is not being compiled/linked or you have a misspelling in it