Im trying to create a DLL consisting of C++ classes including inheritance. The DLL is supposed to be accessed by some console application.
Parent class:
paramCalculator.h
#ifdef MY_EXPORTS
#define PARAMCALCULATOR __declspec(dllexport)
#else
#define PARAMCALCULATOR __declspec(dllimport)
#endif
class PARAMCALCULATOR paramCalculator
{
public:
paramCalculator();
~paramCalculator();
float m_current;
};
paramCalculator.cpp
#include "stdafx.h"
paramCalculator::paramCalculator()
{
}
paramCalculator::~paramCalculator()
{
}
Child class:
currentCalculator.h
#ifdef MY_EXPORTS
#define PARAMCALCULATOR __declspec(dllexport)
#else
#define PARAMCALCULATOR __declspec(dllimport)
#endif
class PARAMCALCULATOR currentCalculator :
public paramCalculator
{
public:
currentCalculator();
~currentCalculator();
float m_tubePower = 1500;
float m_tubeCurrent;
void calcCurrent(float vo);
};
currentCalculator.cpp
#include "stdafx.h"
currentCalculator::currentCalculator()
{
}
currentCalculator::~currentCalculator()
{
}
void currentCalculator::calcCurrent(float vo)
{
m_tubeCurrent = m_tubePower / vo;
std::cout << m_tubeCurrent << std::endl;
m_current = m_tubeCurrent;
}
The console application accessing the DLL looks as follows:
#include "paramCalculator.h"
#include "currentCalculator.h"
class tubeCurrent
{
public:
tubeCurrent() {};
~tubeCurrent() {};
void setParam(float v)
{
ab.calcCurrent(v);
m_current = ab.m_tubeCurrent;
}
currentCalculator ab;
float m_current;
};
int main()
{
tubeCurrent ac;
float voltage = 200;
ac.setParam(voltage);
}
When running the console application it shows "7.5" on the output window, which is the expected calculated value for the current. This tells me that accessing the DLL works. However, the variables m_tubeCurrent and m_current have not been changed to value 7.5. Can anyone tell me how to fix this and get both variables to update its values?
During some tests i've found out that as soon as I remove the inheritance relation between both classes, the member variable "m_tubeCurrent" are updated successfully. However, im struggling to find a way to access the member variables when inheritance between both classes is involved.
I've gone through this question but couldn't solve my issue.
Thanks in advance!
Edit:
In order to make myself more clear, here's two images of the debug window within the console application.
Inheritance is included and the calculated values are not assigned to the corresponding variables:
No inheritance resulting in the calculated values being assigned to the corresponding variables:
In the latter one, I have only changed the currentCalculator class definition within the currentCalculator.h file from
class PARAMCALCULATOR currentCalculator :
public paramCalculator:
to
class PARAMCALCULATOR currentCalculator
Both variants calculate the values in the right manner when the DLL is executed, however only the latter one allows me to still access the variables after the DLL has been executed.
Related
I have read several questions about this problem at SO but the suggested solution is to do the UPDATE 4. I have already installed update-4 to my VS 2012 Ultimate. But still I am not able to get the UML diagram.
My Step:
Go to the architecture tab in VS 2012 Ultimate
select "New Diagram"
select "UML Class Diagram"
then choose the name etc.
the go to "Architecture Explorer"
Drop the classes for which you want to generate UML diagram.
Just to check if there is some other probelm, I wrote a simple program of two classes. In this program, the variable of one class is set by the variable of second class. But there is no UML diagram get generated for the following program.
ERRORS:
Reverse engineer C++ type is not supported. Some DGML node(s) will be skipped during the process. Please see warnings for details.
(0) type(s) fully reverse engineered.
Warnings:
<Warning Timestamp="2015-09-01T09:45:05" Importance="Medium" Text="Reverse engineer C++ type 'Class1' is skipped." />
<Warning Timestamp="2015-09-01T09:45:05" Importance="Medium" Text="Reverse engineer C++ type 'Class2' is skipped." />
My code:
Class1
#ifndef HEADER1_H
#define HEADER1_H
class Class1 {
private:
int value;
public:
void setValue(int value);
void showValue();
};
#endif
Class2:
#ifndef HEADER_H
#define HEADER_H
#include "Header1.h"
class Class2 {
public:
int secondClassValue;
void setValue(int val);
Class1 *class1;
};
#endif
main():
#include <iostream>
#include "Header1.h"
#include "Header.h"
using namespace std;
void Class1::setValue(int value) {
this->value = value;
}
void Class1::showValue() {
cout<<"The value of second class variable is: "<<this->value<<endl;
}
void Class2::setValue(int val) {
secondClassValue = val;
}
int main() {
Class1 *class1 = new Class1;
Class2 *class2 = new Class2;
class2->setValue(10);
class1->setValue(class2->secondClassValue);
//See the set value
class1->showValue();
delete class1;
delete class2;
return 0;
}
I am doing a network simulation using Omnet++ which is based on C++. I am trying to define a class for a certain module using the following code:
#ifndef __PROJECT_IMS_SLF_H_
#define __PROJECT_IMS_SLF_H_
#include <omnetpp.h>
#include "mDIAMETER_m.h"
#include "IPPacket_m.h"
class SLF : public cSimpleModule
{
public:
mDIAMETER *generateDIAMETERmsg(const char* name, long userID, bool registered, std::string server);
IPPacket *generateIPPacket(int srcIP,int desIP);
protected:
virtual void initialize();
virtual void handleMessage(cMessage *msg);
private:
int MyIP;
int N = par("N");
struct Registry {
long UserID;
bool Registered;
std::string Server;
};
struct Registry MyReg[N]; // Create a Registry Table for all UEs
};
#endif
I am getting the following error: "invalid use of non-static data member SLF::N". I know I'm declaring N inside the class definition as a private variable but I have to do so because N is a parameter related to the module which is defined as an instance of the class SLF and it is read from the configurations of this module using the OMNET++ defined function "par".
If I declareMyReg[N]inside the initialize function it works but the problem is that I need to use this variable inside the other function (handleMessage). Any hints?
Thanks in advance!
Allocate the array on the heap:
class SLF /* etc. */
{
/* etc. */
virtual void initialize()
{
/* etc. */
N = par("N");
MyReg = new Registry[N];
/* etc. */
}
/* etc. */
int N;
/* etc. */
struct Registry *MyReg;
}
And be sure to delete the memory in a destructor.
Problem solved as follows:
First, define a pointer to the instance of this structure:
struct Registry *MyReg;
Now inside the module, within the initialize function, N can be read and the instance of the structure can be declared with its size:
int N = par("N");
this->MyReg = new struct Registry[N];
I also defined a finish module withtin the header file and deleted MyReg inside that function.
I have a few enums in my program and I want to share it across different classes.
When I tried to define it in each class I got a "redefining" error.
Then I searched Google and saw that I should put it in a different header.
I tried to to do that and included the header into every class header - I still got the same error.
Searched some more and found in StackOverflow a thread saying I should put them in their own namespace.
So I tried:
enum.h:
namespace my_enums
{
enum classification {DATA_STORAGE,DMS,E_COMMERCE,GAMING,RTES,SECURITY};
enum skill { CPP, JAVA, SCRIPT, WEB, SYSTEM, QA };
enum company_policy {CHEAP, LAVISH, COST_EFFECTIVE};
}
But that still doesn't work: First, if tell classes that include the header to: "using namespace my_enums;" I get " is ambiguous" error.
What is the correct way to do what I'm trying to do?
Thanks in advance ^_^
Did you remember the multiple inclusion guard? Normally looks like:
#ifndef MY_HEADER_FILE_H
#define MY_HEADER_FILE_H
[...code...]
#endif
and protects types and enums from getting defined multiply in a compilation unit.
You only need to declare your enums once in a header if you wish and include that header where you use the enums:
//enum.h:
//include guards:
#ifndef MY_ENUMS
#define MY_ENUMS
namespace my_enums
{
enum classification {DATA_STORAGE,DMS,E_COMMERCE,GAMING,RTES,SECURITY};
enum skill { CPP, JAVA, SCRIPT, WEB, SYSTEM, QA };
enum company_policy {CHEAP, LAVISH, COST_EFFECTIVE};
}
#endif
//A.h
#include "enum.h"
class A
{
void check()
{
my_enums::skill val = my_enums::SCRIPT;
}
};
Maybe you've included it more then once?
Don't forget to add "guards" on include
#ifndef MY_ENUM_H_
#define MY_ENUM_H_
.... enter your enums here ...
#endif // MY_ENUM_H_
struct Classification
{
enum Enum{ dataStorage, dms, eCommerce, gaming, rtes, security }
};
struct Skill
{
enum Enum{ cpp, java, script, web, system, qa };
};
struct CompanyPolicy
{
enum Enum{ cheap, lavish, cost_effective };
};
void whatever( Classification::Enum classification ) {}
class A
: protected Classification
{
public:
void foo() { whatever( dataStorage ); }
};
class B
{
public:
void foo() { whatever( Classification::dataStorage ); }
};
I have exported a C++ class and now i want to use its public member function. how i can do it?
I want to have dynamic binding. My exported class looks like this
#ifdef MAKEDLL
#define DECLDIREXP __declspec(dllexport)
#else
#define DECLDIREXP __declspec(dllimport)
#endif
class DECLDIREXP xyz
{
public:
void printing();
void printing(int a);
};
using namespace std;
void xyz::printing()
{
cout<<"hello i donot take any argument";
}
void xyz::printing(int a)
{
cout<<"hello i take "<< a <<"as argument";
}
it seems you are almost there.
When building the project generating the dll, make sure MAKEDLL is defined for the linker, and the other way round in projects consuming the dll.
By the way MAKEDLL is probably a bad Name, but MAKEFOODLL if your dll is called foo a better one
Can I put a class inside a DLL?
The class i wrote is this:
class SDLConsole
{
public:
SDLConsole();
~SDLConsole(){};
void getInfo(int,int);
void initConsole(char*, char*, SDL_Surface*, int, int, int);
void sendMsg(char*,int, SDL_Surface*);
void cls(SDL_Surface*);
private:
TTF_Font *font;
SDL_Surface *consoleImg;
int width, pos, height, line, size, ctLine;
SDL_Surface* render(char*,int);
};
I know how to load a DLL and use the function inside a DLL, but how can I put a class inside a DLL? Thank you very much.
If you use run time dynamic linking (uses LoadLibrary to load the dll) you cannot access the class directly, you need to declare a interface for your class and create a function that returns a instance of this class, like this:
class ISDLConsole
{
public:
virtual void getInfo(int,int) = 0;
virtual void initConsole(char*, char*, SDL_Surface*, int, int, int) = 0;
virtual void sendMsg(char*,int, SDL_Surface*) = 0;
virtual void cls(SDL_Surface*) = 0;
};
class SDLConsole: public ISDLConsole
{
//rest of the code
};
__declspec(dllexport) ISDLConsole *Create()
{
return new SDLConsole();
}
Otherwise, if you link the dll during load time, just use the information provided by icecrime: http://msdn.microsoft.com/en-us/library/a90k134d.aspx
Solution suggested by bcsanches,
__declspec(dllexport) ISDLConsole *Create()
{
return new SDLConsole();
}
If you're going to use this approach as suggested by bcsanches, then make sure that you use the following function to delete your object,
__declspec(dllexport) void Destroy(ISDLConsole *instance)
{
delete instance;
}
Define such functions always in pair, as it ensures that you delete your objects from the same heap/memory-pool/etc they were created on. See this pair-functions
You can, and all the information you need are on this page and this page :
#ifdef _EXPORTING
#define CLASS_DECLSPEC __declspec(dllexport)
#else
#define CLASS_DECLSPEC __declspec(dllimport)
#endif
class CLASS_DECLSPEC SDLConsole
{
/* ... */
};
All there is left is to define the preprocessor symbol _EXPORTING when building the DLL.
If you want to expose the data in a class, the above solutions won't cut it. You have to slap a __declspec(dllexport) on the class itself in the DLL compilation, and a __declspec(dllimport) in the module that links to the DLL.
A common technique is to do this (Microsoft wizards produce code like this):
#ifdef EXPORT_API
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif
class MY_API MyClass {
...
};
Then make sure EXPORT_API is defined in the DLL project, and make sure it isn't defined in the module that links to the DLL.
If you create a new DLL project in Visual C++ from scratch, and check the check box "Export symbols", some sample code will be generated using this technique.