C++ members using template in non-template class - c++

A clean rebuild in Visual Studio made the whole thing work.
--
In a Visual Studio MFC project, I am making a class to manage buttons.
Here is my problem : I need to add Click Handler at runtime so I can't use Message Map. So I had a clickHandler function pointer in my class, en a function to register the click handler. That was ok for global function, but I want to use class members as ClickHandlers.
After a lot search, I came to this function :
class NRButton : public CButton
{
...
template<class Type>
inline void SetClickHandler(
void (*cb)(CObject * , void (CObject::*)()),
Type * pt,
void (Type::*fn)()
)
{
callbackHandler = cb;
objectHandler = pt;
clickHandler = fn;
}
...
}
This function is implemented inline as you can see, but when I build my project I've got this linker error :
FenetreParametrage.obj : error LNK2019: symbole externe non résolu "public: void __thiscall NRButton::SetClickHandler<class FenetreParametrage>(void (__cdecl*)(class CObject *,void (__thiscall CObject::*)(void)),class FenetreParametrage *,void (__thiscall FenetreParametrage::*)(void))" (??$SetClickHandler#VFenetreParametrage###NRButton##QAEXP6AXPAVCObject##P81#AEXXZ#ZPAVFenetreParametrage##P82#AEXXZ#Z) référencé dans la fonction "public: virtual int __thiscall FenetreParametrage::OnInitDialog(void)" (?OnInitDialog#FenetreParametrage##UAEHXZ)
After cleaning the error message I've got that :
FenetreParametrage.obj : error LNK2019: symbole externe non résolu "
public: void __thiscall NRButton::SetClickHandler<class FenetreParametrage>(
void (__cdecl*)(class CObject *,void (__thiscall CObject::*)(void)),
class FenetreParametrage *,
void (__thiscall FenetreParametrage::*)(void)
)
"
référencé dans la fonction "
public: virtual int __thiscall FenetreParametrage::OnInitDialog(void)
"
I understand this error message, but I don't understand why it appears, my function declared inline, so why VS Compiler can't find its implementation ?
Thanks for your help
EDIT :
Here is the call to the function :
bouton->SetClickHandler(
&FenetreParametrage::Callback,
this,
&FenetreParametrage::OnBoutonClick
);

Related

UE4 LNK2001 Error when deriving from K2Node_AnimGetter

I am trying to derive from K2Node_AnimGetter to add some functionality to it.
However I get some unresolved external symbol LNK2001 errors when I try to compile it.
I have no problem to compile when deriving from K2Node_CallFunction (from what AnimGetter derive itself).
I tried to include some dependencies like AnimGraph in the MyGameEditor.Build.cs but with no result...
Am I missing something ?
K2Node_MyAnimGetter.h
#pragma once
#include "CoreMinimal.h"
#include "K2Node_AnimGetter.h"
#include "K2Node_MyAnimGetter.generated.h"
UCLASS()
class MYGAMEEDITOR_API UK2Node_MyAnimGetter : public UK2Node_AnimGetter
{
GENERATED_BODY()
};
K2Node_MyAnimGetter.cpp
#include "K2Node_MyAnimGetter.h"
// nothing else since my class is empty
MyGameEditor.Build.cs
using UnrealBuildTool;
public class MyGameEditor : ModuleRules
{
public MyGameEditor(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "BlueprintGraph", "AnimGraph", "AnimGraphRunTime" });
PrivateDependencyModuleNames.AddRange(new string[] { "Engine", "UnrealEd", "BlueprintGraph", "AnimGraph", "AnimGraphRunTime", "KismetCompiler" });
}
}
Error logs :
1>K2Node_MyAnimGetter.cpp.obj : error LNK2001: symbole externe non resolu "public: virtual void __cdecl UK2Node_AnimGetter::Serialize(class FArchive &)" (?Serialize#UK2Node_AnimGetter##UEAAXAEAVFArchive###Z)
1>K2Node_MyAnimGetter.gen.cpp.obj : error LNK2001: symbole externe non resolu "public: virtual void __cdecl UK2Node_AnimGetter::Serialize(class FArchive &)" (?Serialize#UK2Node_AnimGetter##UEAAXAEAVFArchive###Z)
1>K2Node_MyAnimGetter.cpp.obj : error LNK2001: symbole externe non resolu "public: virtual void __cdecl UK2Node_AnimGetter::PostPasteNode(void)" (?PostPasteNode#UK2Node_AnimGetter##UEAAXXZ)
1>K2Node_MyAnimGetter.gen.cpp.obj : error LNK2001: symbole externe non resolu "public: virtual void __cdecl UK2Node_AnimGetter::PostPasteNode(void)" (?PostPasteNode#UK2Node_AnimGetter##UEAAXXZ)
1>K2Node_MyAnimGetter.cpp.obj : error LNK2001: symbole externe non resolu "public: virtual void __cdecl UK2Node_AnimGetter::AllocateDefaultPins(void)" (?AllocateDefaultPins#UK2Node_AnimGetter##UEAAXXZ)
1>K2Node_MyAnimGetter.gen.cpp.obj : error LNK2001: symbole externe non resolu "public: virtual void __cdecl UK2Node_AnimGetter::AllocateDefaultPins(void)" (?AllocateDefaultPins#UK2Node_AnimGetter##UEAAXXZ)
1>K2Node_MyAnimGetter.cpp.obj : error LNK2001: symbole externe non resolu "public: virtual class FText __cdecl UK2Node_AnimGetter::GetNodeTitle(enum ENodeTitleType::Type)const " (?GetNodeTitle#UK2Node_AnimGetter##UEBA?AVFText##W4Type#ENodeTitleType###Z)
1>K2Node_MyAnimGetter.gen.cpp.obj : error LNK2001: symbole externe non resolu "public: virtual class FText __cdecl UK2Node_AnimGetter::GetNodeTitle(enum ENodeTitleType::Type)const " (?GetNodeTitle#UK2Node_AnimGetter##UEBA?AVFText##W4Type#ENodeTitleType###Z)
1>K2Node_MyAnimGetter.cpp.obj : error LNK2001: symbole externe non resolu "public: virtual bool __cdecl UK2Node_AnimGetter::CanCreateUnderSpecifiedSchema(class UEdGraphSchema const *)const " (?CanCreateUnderSpecifiedSchema#UK2Node_AnimGetter##UEBA_NPEBVUEdGraphSchema###Z)
1>K2Node_MyAnimGetter.gen.cpp.obj : error LNK2001: symbole externe non resolu "public: virtual bool __cdecl UK2Node_AnimGetter::CanCreateUnderSpecifiedSchema(class UEdGraphSchema const *)const " (?CanCreateUnderSpecifiedSchema#UK2Node_AnimGetter##UEBA_NPEBVUEdGraphSchema###Z)
1>K2Node_MyAnimGetter.cpp.obj : error LNK2001: symbole externe non resolu "public: virtual bool __cdecl UK2Node_AnimGetter::IsActionFilteredOut(class FBlueprintActionFilter const &)" (?IsActionFilteredOut#UK2Node_AnimGetter##UEAA_NAEBVFBlueprintActionFilter###Z)
1>K2Node_MyAnimGetter.gen.cpp.obj : error LNK2001: symbole externe non resolu "public: virtual bool __cdecl UK2Node_AnimGetter::IsActionFilteredOut(class FBlueprintActionFilter const &)" (?IsActionFilteredOut#UK2Node_AnimGetter##UEAA_NAEBVFBlueprintActionFilter###Z)
1>K2Node_MyAnimGetter.cpp.obj : error LNK2001: symbole externe non resolu "public: virtual void __cdecl UK2Node_AnimGetter::GetMenuActions(class FBlueprintActionDatabaseRegistrar &)const " (?GetMenuActions#UK2Node_AnimGetter##UEBAXAEAVFBlueprintActionDatabaseRegistrar###Z)
1>K2Node_MyAnimGetter.gen.cpp.obj : error LNK2001: symbole externe non resolu "public: virtual void __cdecl UK2Node_AnimGetter::GetMenuActions(class FBlueprintActionDatabaseRegistrar &)const " (?GetMenuActions#UK2Node_AnimGetter##UEBAXAEAVFBlueprintActionDatabaseRegistrar###Z)
1>R:\SVN\MyGame\Binaries\Win64\UE4Editor-MyGameEditor.dll : fatal error LNK1120: 7 externes non resolus
If you look into the UK2Node_AnimGetter class you will notice that it is UCLASS(MinimalAPI). This means that the class is accessible outside of its Module, but its internal functions are not exported.
You will also notice that all of the functions with linker errors are virtual override. By overriding these functions you maybe able to export them manually and thus fix the linking errors.

Building release of project with QScintilla

I have project written in C++ that use Qt Framework and QScintilla2. I cannot build Release because of linker errors. I'm using Visual Studio 2013.
Errors:
1>codeditor.obj : error LNK2019: unresolved external symbol "public:
static struct QMetaObject const QsciScintillaBase::staticMetaObject"
(?staticMetaObject#QsciScintillaBase##2UQMetaObject##B) referenced in
function "public: static class QMetaObject::Connection __cdecl
QObject::connect(class QsciScintillaBase const ,void (__thiscall QsciScintillaBase::)(int,int,char const
*,int,int,int,int,int,int,int),class CodeEditor const ,void (__thiscall CodeEditor::)(int,int,char const
*,int,int,int,int,int,int,int),enum Qt::ConnectionType)" (??$connect#P8QsciScintillaBase##AEXHHPBDHHHHHHH#ZP8CodeEditor##AEXHH0HHHHHHH#Z#QObject##SA?AVConnection#QMetaObject##PBVQsciScintillaBase##P83#AEXHHPBDHHHHHHH#ZPBVCodeEditor##P84#AEXHH1HHHHHHH#ZW4ConnectionType#Qt###Z)
1>codeditor.obj : error LNK2019: unresolved external symbol "public:
static struct QMetaObject const QsciScintilla::staticMetaObject"
(?staticMetaObject#QsciScintilla##2UQMetaObject##B) referenced in
function "public: static class QMetaObject::Connection __cdecl
QObject::connect),void (__thiscall
CodeEditor::*)(int,int,class QFlags)>(class
QsciScintilla const ,void (__thiscall QsciScintilla::)(int,int,class
QFlags),class CodeEditor const ,void
(__thiscall CodeEditor::)(int,int,class QFlags),enum Qt::ConnectionType)"
(??$connect#P8QsciScintilla##AEXHHV?$QFlags#W4KeyboardModifier#Qt#####ZP8CodeEditor##AEXHH0#Z#QObject##SA?AVConnection#QMetaObject##PBVQsciScintilla##P83#AEXHHV?$QFlags#W4KeyboardModifier#Qt#####ZPBVCodeEditor##P85#AEXHH1#ZW4ConnectionType#Qt###Z)
1>release\JSD-V8-QT.exe : fatal error LNK1120: 2 unresolved externals

Polymorphism with smart pointers using templates

I'm having trouble putting a shared_ptr of sf::Text, sf::Sprite and sf::Text into an array of shared_ptr
sf::Drawable is the mother class of all the above and is abstract
Here's the game engine function:
GameEngine.h
template<class T>
void add(std::shared_ptr<T> actor);
GameEngine.cpp
template<>
void GameEngine::add<sf::Drawable>(std::shared_ptr<sf::Drawable> actor)
{
drawables.insert(actor);
}
Rendering.cpp
void Rendering::addDrawable(std::shared_ptr<sf::Sprite> sprite, sf::Vector2i texture_rect, const char* texture_name)
{
sf::Texture* _texture = engine.lock()->getGameData().getTexture(texture_name);
if (_texture) {
sprite->setTexture(*_texture);
sprite->setTextureRect(sf::IntRect(0, 0, texture_rect.x, texture_rect.y));
//What do i have to put in the below function?
engine.lock()->add(sprite);
}
}
I'm getting the following error in VS 2015:
1>Rendering.obj : error LNK2019: symbole externe non résolu "public: void __thiscall GameEngine::add<class sf::Sprite>(class std::shared_ptr<class sf::Sprite>)" (??$add#VSprite#sf###GameEngine##QAEXV?$shared_ptr#VSprite#sf###std###Z) référencé dans la fonction "public: void __thiscall Rendering::addDrawable(class std::shared_ptr<class sf::Sprite>,class sf::Vector2<int>,char const *)" (?addDrawable#Rendering##QAEXV?$shared_ptr#VSprite#sf###std##V?$Vector2#H#sf##PBD#Z)
1>Rendering.obj : error LNK2019: symbole externe non résolu "public: void __thiscall GameEngine::add<class sf::Shape>(class std::shared_ptr<class sf::Shape>)" (??$add#VShape#sf###GameEngine##QAEXV?$shared_ptr#VShape#sf###std###Z) référencé dans la fonction "public: void __thiscall Rendering::addDrawable(class std::shared_ptr<class sf::Shape>,char const *)" (?addDrawable#Rendering##QAEXV?$shared_ptr#VShape#sf###std##PBD#Z)
1>Rendering.obj : error LNK2019: symbole externe non résolu "public: void __thiscall GameEngine::add<class sf::Text>(class std::shared_ptr<class sf::Text>)" (??$add#VText#sf###GameEngine##QAEXV?$shared_ptr#VText#sf###std###Z) référencé dans la fonction "public: void __thiscall Rendering::addDrawable(class std::shared_ptr<class sf::Text>,char const *,char const *,class sf::Color)" (?addDrawable#Rendering##QAEXV?$shared_ptr#VText#sf###std##PBD1VColor#sf###Z)
Is there a way to put a shared pointer of a subclass into an array of shared pointers of its mother class?
EDIT:
An answer said that:
Just because Sprite is a subclass of Drawable, does not mean that
shared_ptr<Sprite> is a subclass of shared_ptr<Drawable>.
Then why can i do this?
class A{};
class B : public A {};
int main() {
std::vector<std::shared_ptr<A>> ar;
ar.push_back(std::make_shared<B>());
return 0;
}
Just because Sprite is a subclass of Drawable, does not mean that shared_ptr<Sprite> is a subclass of shared_ptr<Drawable>.
When the compiler sees this:
engine.lock()->add(sprite);
it looks for a member function add(shared_ptr<sf::Sprite>) following the overload resolution rules.
Even though shared_ptr<Sprite> is not a subclass of shared_ptr<Drawable>, there is an implicit conversion available, so it would be a candidate.
However this:
template<class T>
void add(std::shared_ptr<T> actor);
provides a declaration of the function for any type, but no definition. Therefore it provides an exact match and will be chosen by the compiler. That is why you get linker errors.
One way to solve this is to use std::static_pointer_cast, like this:
engine.lock()->add(std::static_pointer_cast<Drawable>(sprite));
I would also reconsider if/why you need the template above - I can't see what purpose that is serving, other than to give you link time errors instead of compile time errors.

c++ (constructor) inheritance - LNK 2019 error [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is an undefined reference/unresolved external symbol error and how do I fix it?
I have a LNK error that involves a class A and its derived class B. More precisely, I have this compilation error
Error 239 error LNK2019: unresolved external symbol "public: virtual __thiscall A::~A(void)" (??1A##UAE#XZ) referenced in function "public: virtual __thiscall B::~B(void)" (??1B##UAE#XZ) D:\Products\path\file.lib(B.obj)
Error 240 error LNK2019: unresolved external symbol "public: __thiscall A::A(void)" (??A##QAE#XZ) referenced in function "public: __thiscall B::B(void)" (??B##QAE#XZ) D:\Products\path\file.lib(B.obj)
Error 241 error LNK2019: unresolved external symbol "public: void __thiscall A::function(float * *,float * *,float * *,float * *,int)" (?function#A##QAEXPAPAM000H#Z) referenced in function "public: class SomeType* __thiscall B::function_bis(void)" (?function_bis#B##QAEPAVSomeType##XZ) D:\Products\path\file.lib(B.obj)
I guess this may be related to, say, call of inherited constructor, or the non-respect of the signature in some call of function() or function_bis(). However, such mistakes i cannot find.
Do you have a hint to a possible way to solve ? Here is code for (simplified) A and B.
B.cpp
B::B(void)
{
}
B::B(Type1* d1, Type1* d2, Type1* r):A()
{
D1= d1;
D2= d2;
R= r;
}
B::~B( void )
{
}
SomeType* B::function()
{
// do things
function_bis() ;
}
B.h
class B:
public A
{
public:
B(void) ;
B(Type1* , Type1* , Type1* );
virtual ~B(void);
SomeType* function() ;
private:
Type1* D1;
Type1* D2;
Type1* R;
};
A.cpp
using namespace std ;
A::A(void){}
A::~A(void){}
void A::function_bis(float** d, float** d2, float** d3, float** d4, int n)
{}
A.h
class A
{
public:
A(void);
virtual ~A(void);
void function_bis(float** , float** , float** , float** , int );
};
Thanks!
Everything looks legit in your code.
My guess is that you actually don't compile A.cpp or somehow you don't include the resulting object file in your linking step (you miss A::A, A::~A and A::function_bis which are defined in A.cpp).

Receiving an error based on template class and it's child class's function calls

1>main.obj : error LNK2019: unresolved external symbol "public: virtual bool __thiscall LinkedSortedList<int>::getfirst(int &)" (?getfirst#?$LinkedSortedList#H##UAE_NAAH#Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall LinkedSortedList<int>::clear(void)" (?clear#?$LinkedSortedList#H##UAEXXZ) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall LinkedSortedList<int>::print(void)const " (?print#?$LinkedSortedList#H##UBEXXZ) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: virtual bool __thiscall LinkedSortedList<int>::insert(int)" (?insert#?$LinkedSortedList#H##UAE_NH#Z) referenced in function _main
1>main.obj : error LNK2001: unresolved external symbol "public: virtual bool __thiscall LinkedSortedList<int>::find(int)const " (?find#?$LinkedSortedList#H##UBE_NH#Z)
1>main.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall LinkedSortedList<int>::size(void)const " (?size#?$LinkedSortedList#H##UBEHXZ)
1>c:\users\chris\documents\visual studio 2010\Projects\lab0\Debug\lab0.exe : fatal error LNK1120: 6 unresolved externals
This is what I recieve when trying to compile my code. I've narrowed it down to (i believe) this section of code here:
#ifndef _LinkedSortedListClass_
#define _LinkedSortedListClass_
#include "LinkedNode.h"
#include "SortedList.h"
template <class Elm>
class LinkedSortedList: public SortedList<int> {
public:
void clear();
bool insert(Elm newvalue);
bool getfirst(Elm &returnvalue);
void print() const;
bool find(Elm searchvalue) const;
int size() const;
private:
LinkedNode<Elm>* head;
};
#endif
This is the child class of the SortedList, which is this, in case it's needed..
#ifndef _SortedListClass_
#define _SortedListClass_
template <class Elm> class SortedList {
public:
// -------------------------------------------------------------------
// Pure virtual functions -- you must implement each of the following
// functions in your implementation:
// -------------------------------------------------------------------
// Clear the list. Free any dynamic storage.
virtual void clear() = 0;
// Insert a value into the list. Return true if successful, false
// if failure.
virtual bool insert(Elm newvalue) = 0;
// Get AND DELETE the first element of the list, placing it into the
// return variable "value". If the list is empty, return false, otherwise
// return true.
virtual bool getfirst(Elm &returnvalue) = 0;
// Print out the entire list to cout. Print an appropriate message
// if the list is empty. Note: the "const" keyword indicates that
// this function cannot change the contents of the list.
virtual void print() const = 0;
// Check to see if "value" is in the list. If it is found in the list,
// return true, otherwise return false. Like print(), this function is
// declared with the "const" keyword, and so cannot change the contents
// of the list.
virtual bool find(Elm searchvalue) const = 0;
// Return the number of items in the list
virtual int size() const = 0;
};
#endif
Thanks so much for any help; our last class taught us nothing of inheritance, but this is project #1 for this class, without being taught inheritance here either, so this is all touch and go for me, despite what I managed to look up on Google.
Your methods aren't defined. So the linker is complaining because it can't link to their definitions.
Maybe it helps if you placed the definitions of your functions in your header file. This makes it easier for the compiler to resolve these external symbols.
I hope this will help.
Regards,
Philinator