How to define the function out side the Library? - c++

we have some dynamic plugin-dll, which is generated through separate protect, and use while the software is start. Plugin-dll code is use some of header file from main project. while compiling plugin code, If main project header file contain some function, and definition outside the class, at that time I am getting error like unresolved external symbol.
This error are expected because of plugin code does not find the definition of (main project) function.
Note: plugin must be compile before compilation of main project.
In two situation plug in code is compile.
1) If main project header file has pure virtual function then it is work
perfectly (plug code is compile fine).
2) If I will write the function definition inside the class.
I tried inline function but it is did not work.
---------------------
*** Main Project ***
---------------------
->This project generate .exe file
mainProject.h
-------------
class MainProjectHeder{
virtual void foo() = 0; // this function is work
void foo1(); // this function giving me error like unresolved external symbol
void foo2{ // this work
print("hello");
};
};
void MainProjectHeder::foo1(){
print("function not working");
}
ExperimentFactoryInterface.h
----------------------------
#include <MainProjectHeder.h>
class ExperimentFactoryInterface {
public:
virtual ~ExperimentFactoryInterface() {}
virtual MainProjectHeder* CreateExperiment(const QVariant& = QVariant()) = 0;
};
----------------------
*** Pulgin code ***
----------------------
->This Project is generate DLL file
Experiment.h
-------------
#include <mainProject.h>
class Experiment : public MainProjectHeder{
virtual void foo();
};
void Experiment:foo(){
print("work fine");
}
Factory.h
----------
#include "cyclicvoltammetry.h"
#include <ExperimentFactoryInterface.h>
class Factory : public ExperimentFactoryInterface {
public:
MainProjectHeder* CreateExperiment(const QVariant& = QVariant());
};
MainProjectHeder* Factory::CreateExperiment(const QVariant&) {
return new Experiment;
}
while compiling code of plugIn; how can I inform to compiler like definition of function void foo1(); is write out side the project or in another project?

A member function of a class is a function that has its definition or its prototype within the class definition like any other variable. It operates on any object of the class of which it is a member, and has access to all the members of a class for that object.

Related

expected type-specifier before error with unique_ptr in c++

In below code while compiling i am getting error ,
Error :
main.cpp:8:57: error: expected type-specifier before ‘Staircase’
std::unique_ptr algodiagnostic (new Staircase());
compilation command
g++ HardwareDiagnostic.cpp HardwareDiagnostic.h main.cpp -std=c++0x -o res
it works fine if compile entire code in single file without creating header file and main.cpp separately. Can anybody suggest how to fix this issue.
//HardwareDiagnostic.h//
#ifndef HARDWAREDIAGNOSTIC_H_
#define HARDWAREDIAGNOSTIC_H_
#include <iostream>
#include <memory>
using namespace std;
class HardwareDiagnostic
{
public:
virtual bool checkPort();
virtual void startDiagnostic();
virtual int publishAlgoDiagnosticInfo();
virtual void clearErrorStatus(){cout<<"Algorithm Diagnostics"<<endl;}
virtual ~HardwareDiagnostic() {cout<<"calling virtual destructor"<<endl;}
};
#endif /* HARDWAREDIAGNOSTIC_H_ */
//HardwareDiagnostic.cpp//
#include"HardwareDiagnostic.h"
class Localization : public HardwareDiagnostic
{
public:
Localization() { cout << "calling Localization constructor";}
bool checkPort(){cout<<"checkport :Localization";}
void startDiagnostic(){cout<<"start Diagnostic:Localization";}
int publishAlgoDiagnosticInfo() {cout<<"publish Diagnostic:Localization";}
void clearErrorStatus(){ cout<<"Localization:publish Diagnostic";}
~Localization () { cout<<"calling Localization destructor ";}
};
class Staircase : public HardwareDiagnostic
{
public:
Staircase () {cout<<"Staircase constructor";}
bool checkPort(){cout<<"Staircase";}
void startDiagnostic(){cout<<"StairCase:start Diagnostic";}
int publishAlgoDiagnosticInfo() {cout<<"StairCase:publish Diagnostic";}
void clearErrorStatus(){ cout<<"staircase:publish Diagnostic";}
~Staircase(){cout<<"calling Staircase destructor";}
};
//main.cpp//
#include "HardwareDiagnostic.h"
using namespace std;
int main() {
std::unique_ptr<HardwareDiagnostic> algodiagnostic (new Staircase());
return 0;
}
When compiler works on main.cpp, it sees Staricase usage, but doesn't see declaration for Staircase class, so error is raised. Your main.cpp file includes header, which describes HardwareDiagnostic class only, but no info for Staircase is provided.
Good practice is to keep class declarations in header files, rather than cpp files, so any other source can include header file and start using described class. It's OK to include definition for trivial class methods in header file as well (like getters/setters), but complicated methods should be declared in header file and defined in coresponding cpp file.
In your case I would do the following:
HardwareDiagnostic.h describes HardwareDiagnostic class. There is no using std line in this file, so anyone including this file won't implicitly start using undesired namespace. All methods are declared, but not defined.
HardwareDiagnostic.cpp defines methods of HardwareDiagnostic class. So there is using std line and definition of all methods.
Localization.h includes HardwareDiagnostic.h and describes Localization class. Having separate file for each class becomes very convenient as project grows.
Localization.cpp defines methods of Localization class.
Staircase.h and Staircase.cpp are built the same way as localization.
main.cpp includes HardwareDiagnostic.h and Staircase.h

What C++ compiler/linker does when using runtime DLL loading?

I would like to understand the DLL mechanism and what the compiler does when I loads the DLL at run-time (i.e. I will not use the generated .lib).
Consider the following C++ code:
DLL interface header file
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif
class MYDLL_API Base
{
public:
Base();
virtual ~Base();
virtual int get_number() const;
virtual const char* what() const = 0;
private:
int i_;
};
class MYDLL_API Child : public Base
{
public:
Child();
virtual ~Child();
virtual int get_number() const override;
virtual const char* what() const override;
private:
int j_;
};
extern "C" {
MYDLL_API Base* __cdecl initializeObject();
}
DLL implementation source file
#include "MyDLL.hh"
Base::Base()
: i_(42)
{}
Base::~Base()
{}
int Base::get_number() const
{
return i_;
}
Child::Child()
: Base()
, j_(24)
{}
Child::~Child()
{}
int Child::get_number() const
{
return j_;
}
const char* Child::what() const
{
return "Hello!";
}
Base* initializeObject()
{
return new Child();
}
The goal of this DLL is to have a common interface defined by the Base class, but it allows specifics implementations compiled in different DLLs that are loaded at runtime (here the Child class is exposed for the purpose of the example).
At this stage, if I naively include the DLL's header:
#include "MyDLL.hh"
int main()
{
Base* b = new Child();
std::cout << b->get_number() << std::endl;
std::cout << b->what() << std::endl;
delete b;
getchar();
return 0;
}
The linker complains LNK2019 and LNK2001 errors: it can not resolves symbols. So, it behaves as expected (I did not use the .lib).
Consider now, the following code that I use to load the DLL at runtime:
#include "MyDLL.hh"
typedef Base* (*initFuncType)();
int main()
{
HINSTANCE handle = LoadLibrary(L"MyDLL.dll");
initFuncType init = nullptr;
init = (initFuncType)(GetProcAddress(handle, "initializeObject"));
if (init)
{
Base* b = init(); //< Use init() !
std::cout << b->get_number() << std::endl;
std::cout << b->what() << std::endl;
delete b;
}
getchar();
FreeLibrary(handle);
return 0;
}
This time it works, the linkage is done.
1st question: What happened? What changed for the compiler and the linker? The use of the function pointer on initializeObject() solves the problem.
The other issue I do not understand well is when I remove virtual and override of get_number():
int get_number() const;
I have a LNK2019 error because of the unresolved Base::get_number(void) const symbol in the _main function. I understand that the virtual keyword will resolve the member function dynamically (at run-time). In our case, the DLL is not loaded yet, the get_number symbol is not available.
2nd question: Does this means that methods must always be virtual using DLL run-time linking?
3rd question: How can I have the C++ function exportation with the Windows API? So that I could remove the extern "C" { ... } stuff.
Thanks for your reading! I hope I will read interesting answers! :)
There are two ways to link dll files.
The 2nd way (the way it works) is the C Binding approach, where you query the dll for a specific function name and it returns a functor to you.
Using the 2nd way you won't be able to extend the base classes, since they are not defined (you don't have any code to be copy pasted so to speak at linkage time).
In order to have a dll who's classes can be extended, you will need to use dynamic binding. You need to compile your .dll and also provide a Symbols Library (or an export library). You have this option in VS studio in project properties.
The mechanism is as following :
Compile Dll project -> output : myLib.dll , myLib.lib
Use exported symbols from myLib.lib inside your main project (main project takes myLib.lib as dependency)
at runtime,due to the binding, your program will know it requires myLib.dll to work so it will load it (if found, else you get runtime error)
Another advantage of using Export Library is that you can export C++ functions (which are mangled on export).
It's very hard to have C Binding on mangled functions.
C Binding on the otherhand, compared to the dynamic binding, won't make your program scream if myLib.dll isn't found , you will just get a null pointer to function.

Calling function from different files in C++ error

I would like to use one function from Stats.cpp in Application.cpp. Here are my code snippets:
In Stats.h:
#ifndef STATS_H
#define STATS_H
class Stats
{
public:
void generateStat(int i);
};
#endif
In Stats.cpp:
#include Stats.h
void generateStat(int i)
{
//some process code here
}
In Application.cpp:
int main()
{
generateStat(10);
}
I get an "unresolved external symbol" error however I don't know what I else I would need to include in order for Application.cpp. Any thoughts?
In Stats.cpp
you need to define generateStat like following :
#include Stats.h
void Stats:: generateStat(int i) // Notice the syntax, use of :: operator
{
//some process code here
}
Then create object of class Stats, use it to call the public member function generateStat
Stats s;
s.generateStat( 10 ) ;
Build the application using :
g++ -o stats Stats.cpp Application.cpp -I.
generateStat is part of your Stats class. You need to instantiate a Stats object (along with the necessary includes for Stats.h in your main class)
For example,
Stats stat;
stat.generateStat(i);
Also, your function definition needs to include the class name Stats::generateStat.
The same error msg occured 2 weeks ago (at work).
At first glance --- Try:
void Stats::generateStat(int i) {
//some process code here }
The class name was missing. Hence, unresolved.
btw Concerning your header --- another issue, this #ifndef directive should not be necessary cause you should declare Stats only once in a namespace.
#ifndef CLASS_H
#define CLASS_H
#include "Class.h"
#endif
This is a generic example - Usable in cpp files.
EDIT: Now, I saw your invocation (main method in your case). You need an object instance to invoke your method.
Stats* stats = new Stats(); //add a default constructor if not done
stats->generateStat(77);
// any other stats stuff ......
// in posterior to the last use
delete(stats);
In your header:
Stats::Stats(){}; //with an empty body - no need to write it again in the cpp file

Is it possible to keep a naked class definition without declaring it's methods?

Prior to refactoring my previous question, which I believe was a little bit off...
The title pretty much asks my question.
How can I keep a class definition on it's own without giving it methods & producing the error below?
The reason for this is because I want to create an object in a separate DLL (which contains the methods), but only return a reference pointer to my main program.
This is explicit exporting by the way.
Error 1 error LNK2001: unresolved external symbol "public: int
__thiscall ObjTest::getValue(void)" (?getValue#ObjTest##QAEHXZ)
class ObjTest
{
private:
int x;
public:
int getValue();
};
Since you need to load the .dll with LoadLibrary(), you can expose a pure virtual class, and have the .dll return a sub class of it:
You separate them in two files:
File ObjTest.h:
class ObjTest
{
public:
virtual int getValue() = 0;
};
ObjTest *CreateObjTest();
File ObjTest.cpp:
#include "ObjTest.h"
class ObjTestImpl : public ObjTest
{
int x;
public:
virtual int getValue();
};
int ObjTestImpl::getValue()
{
return x;
}
ObjTest *CreateObjTest()
{
return new ObjTestImpl();
}
You compile ObjTest.cpp and create a .dll out of it. Your main executable program will need to LoadLibrary() your .dll, use GetProcAddress() to extract the CreateObjTest as a function pointer and call it to return a new ObjTest .
(You might have to create a DeleteObjTest() function too - if your main executable and .dll end up with a different CRT, they'll have different heaps, so you need to call into the .dll instead of just doing delete myObj.)
The other approach is to wrap everying in a C API, and just pass opaque handles to C functions across the .dll instead of dealing with C++ objects.
You are confusing definition and implementation. You have the method defined but not implemented. Hence, the compiler compiles the code without error, as the method is defined, the linker creates an error as there is no implementation for the method (undefined symbol).
The DevStudio compiler does let you import classes from DLLs into an application:-
class __declspec (dllimport) ClassName
{
// members, etc
}
and in the DLL source, change the 'dllimport' to 'dllexport'.
See this MSDN article for more information.
If you want to hide the data members and the private methods then you'd need to look into the pimpl idiom.

Public Static Variable access

I'm tring to expose a static variable. I have tried doing this as both just a public static, and using access functions, but when I use the command Stage::SetFramework( this ); in my Framework class, or even if I make systemFramework public and use Stage::systemFramework = this, I get:
framework.obj||error LNK2001: unresolved external symbol "public: static class Framework * Stage::systemFramework" (?systemFramework#Stage##2PAVFramework##A)|
I'm not sure why this isn't working. I'm obviously missing something Can anyone help please?
#pragma once
#include "event.h"
#ifndef Framework
class Framework;
#endif // Framework
class Stage
{
protected:
static Framework* systemFramework;
public:
// static Framework* systemFramework;
// Stage control
virtual void Begin() = 0;
virtual void Pause() = 0;
virtual void Resume() = 0;
virtual void Finish() = 0;
virtual void Event(FwEvent *e) = 0;
virtual void Update() = 0;
virtual void Render() = 0;
static void SetFramework( Framework* FrameworkObject )
{
systemFramework = FrameworkObject;
};
/*
static Framework* GetFramework()
{
return systemFramework;
};
*/
};
Thanks
Listing static class data members in a class only declares them. They must still be defined somewhere. Put this definition into one .cpp file:
Framework *Stage::systemFramework;
That's because you need a FrameWork* Stage::systemFramework; somewhere too (in a .cpp file, typically). This "places" your variable you may, for example for caching reasons, have it next to some othver variables - so the compiler won't just throw it anywhere, so the declaration inside the class definition is just that, a declaration that "there will be one of these variable somewhere". [Or in an embedded system, there may be some part of memory that is backed up by battery power and another part of memory that isn't, and again, where you "place" the variable will matter in this case].
Of course, the public, private or protected inside the class will still determine which parts of the code can access the variable.