Hallöchen,
hups wie ich grad feststellen muss hab ich gaanz vergessen zu bedanken bei dir
Manchmal hab ich einfach n Brett vorm Kopp
Letztendlich hab ich mir Gedacht um der OOP gerecht zu werden, darf es die einzelnen Devices nur einmal geben mit all ihren Variablen...und sollte eigentlich verhindern das
Kopien erstellt werden können, aber erstma Wurst muss ja irgendwann mal fertig werden^^
Ich hab da ein weiteres Problem, bei dem es zwar um VBA unter Excel geht, es werden nur zwei der C++ dll Interfaces aufgerufen.
Hab bisher immer nen C++ Client benutzt, den ich immer erweitert hab wenn
ein neues Interface dazu kam... Hab dabei nicht einen
Speicherzugriffsfehler oder irgendwelche
Speicherlecks...
Aber wenn VBA den Client spielt läuft da gar nix mit den Variablen Klassen.
Hab den Fehler beim Konstruktor Aufruf der Variable KLassen lokalisert, den Fehler jedoch nicht
Ich wüsste nicht was der VBA Client anders macht als der C++ Client...
Ob der VBA Client vielleicht empfindlicher ist als der C++ Client?
Das ist jetzt recht viel Code ich schau mal das ich was rauslösche ums übersichtlicher zu machen...
Also der Fehler passiert wenn ich eine Variable erstellen möchte durch den Konstruktor einer expliziten Ableitung wie z.B.
Cvar * m_boolVariable = new CTBool(varName, aType, vaddr, numberOfArrayEntries);
Hab dabei die Übergebenen Werte überprüft und ist alles in Ordnung, selbst die Aufrufreihenfolge der Konstruktoren ist korrekt!
Es kommt zu folgendem Fehler wenn ein Konstruktor zum ersten Mal aufgerufen wird:
Diese Info als modales Fenster:
Unbehandelte Ausnahme bei 0x7c911230 in EXCEL.EXE: Benutzerhaltepunkt.
Und ganz viele hiervon im Debugger (schätze für jede Variable die angelegt wird
):
Heap missing last entry in committed range near 2f667c0
Ich hab euch den Code mal stark gekürztz und verschone euch mit allen Methoden, nur das wichtige
//-------------------------------------------------------------------------------------------------------------------
//CVar - Variablenklasse um jede Art von Variablen darstellen zu können
//-------------------------------------------------------------------------------------------------------------------
_MAX_RAWDATA_ARRAY_SIZE = 256
Code:
#pragma once
#include "definitions.h"
#include "Value.h"
class CVar
{
public:
CVar(void);
CVar(CString VarName, AddrType AddrTypeOfVar, long AddressOfVar);
virtual ~CVar(void);
//--------------------------------------------------------------------------------
//Datamember
//--------------------------------------------------------------------------------
private:
CString m_sName; //Variablen Name
AddrType m_eType; //Adress Typ (symbolisch, absolut...)
long m_dwAddress; //Adresse der Variable
public:
CValue * m_Value; //Used 2 save all interpreted Values, also arrays...
BYTE m_abRawData[_MAX_RAWDATA_ARRAY_SIZE]; //Used 2 save all raw data
BYTE GetAddr(LowHighAdresses AddressLowHigh);
//--------------------------------------------------------------------------------
//All get methods:
//--------------------------------------------------------------------------------
CString getVarName(void) {return m_sName;}
//--------------------------------------------------------------------------------
//All std. public methods 4 all DataTypes:
//--------------------------------------------------------------------------------
void setVarName(CString Name); //Changes the var Name
//--------------------------------------------------------------------------------
//All virtual methods that should be implemented by deriving classes...
//--------------------------------------------------------------------------------
virtual bool InterpretRawData(void) PURE; //Muss von jedem Erber implementiert werden und interpretiert die Rohdaten
};
CVar Implementierung:
Code:
#include "StdAfx.h"
#include ".\var.h"
//------------------------------------------------------------------------------------------------------------------------------------------------------
CVar::CVar(void) :
m_sName(""),
m_eType(addrSym),
m_dwAddress(0x00)
{
resetRawData();
}
//--------------------------------------------------------------------------------
CVar::~CVar(void)
{
}
//--------------------------------------------------------------------------------
CVar::CVar(CString VarName, AddrType AddrTypeOfVar, long AddressOfVar):
m_sName(VarName),
m_eType(AddrTypeOfVar),
m_dwAddress(AddressOfVar),
m_Value(NULL)
{
resetRawData();
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
BYTE CVar::GetAddr(LowHighAdresses AddressLowHigh)
{ //TODO: Was gegen die Compiler Warnung tun!
BYTE returnValue;
if(AddressLowHigh == high)
returnValue = (m_dwAddress >> 8) & 255;
else
returnValue = m_dwAddress & 255;
return returnValue;
}
//--------------------------------------------------------------------------------
void CVar::setVarName(CString Name)
{
//ToDo: Überprüfung der Übergebenen Werte!
m_sName = Name;
}
//-------------------------------------------------------------------------------------------------------------------
//CInterInfo - Hilfsklasse um Interpretations Informationen (Verknüpfung zwischen Wert und String) zu speichern
//-------------------------------------------------------------------------------------------------------------------
//CValue - Speicherklasse um alle Werte einer Variable zu speichern (Einfache, Arrays, Interpretierte, usw.
//-------------------------------------------------------------------------------------------------------------------
Code:
#pragma once
#include "definitions.h"
//-------------------------------------------------------------------------------------------------------------------
//CInterInfo - Hilfsklasse um Interpretations Informationen (Verknüpfung zwischen Wert und String) zu speichern
//-------------------------------------------------------------------------------------------------------------------
class CInterInfo
{
public:
CInterInfo(void){;}
CInterInfo(short nFault, CString sFault) : m_nFault(nFault), m_sFault(sFault){;}
~CInterInfo(void){;}
short m_nFault;
CString m_sFault;
};
//-------------------------------------------------------------------------------------------------------------------
//CValue - Speicherklasse um alle Werte einer Variable zu speichern (Einfache, Arrays, Interpretierte, usw.
//-------------------------------------------------------------------------------------------------------------------
class CValue
{
private:
//Std. C´tor should not be used -> private!
CValue();
public:
//User C´tor
CValue(DataClass dataClass, short arrayEntries, short nScaling, bool bIsFloat, bool bInterpretedValue);
//Copy C´tor
CValue(const CValue& x);
//D´tor
~CValue(){delete[] m_aValue; deleteAllInterInfo();}
private:
//--------------------------------------------------------------------------------
//Datamember
//--------------------------------------------------------------------------------
vector <CInterInfo*> m_vValueInterInfo; //Vector that saves all interpretation of the values
vector <CInterInfo*> m_vFaultInterInfo; //Vector that saves all interpretation of the fault
short m_nScaling;
DataClass m_DataClass;
short m_sArrayEntries;
double * m_aValue;
CString m_sValueInter;
int m_nFault;
CString m_sFaultInter;
bool m_bIsFloat;
bool m_bInterpretedValue;
bool m_bValueInvalid;
public:
//--------------------------------------------------------------------------------
//Methods
//--------------------------------------------------------------------------------
short getNbOfArrayEntries(void){return m_sArrayEntries;}
CString getAllDataAsString(void);
void addFaultInterInfo(short nFault, CString sFault);
void addValueInterInfo(double dValue, CString sValue);
void deleteAllInterInfo(void); //Have to be called in D´tor deletes dynamicly allocated Space...
};
CValue Implementierung:
Code:
#include ".\value.h"
CValue::CValue() : m_DataClass(simple),
m_sArrayEntries(1),
m_sValueInter(""),
m_nFault(0),
m_sFaultInter(""),
m_nScaling(1),
m_bValueInvalid(false),
m_bInterpretedValue(false)
{
m_aValue = new double[m_sArrayEntries];
initArray();
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
CValue::CValue(DataClass dataClass, short arrayEntries, short nScaling, bool bIsFloat, bool bInterpretedValue) :
m_DataClass(dataClass),
m_sArrayEntries(arrayEntries),
m_sValueInter(""),
m_sFaultInter(""),
m_nFault(0),
m_nScaling(nScaling),
m_bIsFloat(bIsFloat),
m_bValueInvalid(false),
m_bInterpretedValue(bInterpretedValue)
{
m_aValue = new double[arrayEntries];
initArray();
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
CValue::CValue(const CValue& x) :
m_DataClass(x.m_DataClass),
m_sArrayEntries(x.m_sArrayEntries),
m_sValueInter(x.m_sValueInter),
m_sFaultInter(x.m_sFaultInter),
m_nFault(x.m_nFault),
m_nScaling(x.m_nScaling),
m_bValueInvalid(x.m_bValueInvalid),
m_bInterpretedValue(x.m_bInterpretedValue)
{
m_aValue = new double[x.m_sArrayEntries];
memcpy(m_aValue, x.m_aValue, sizeof(x.m_aValue));
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
bool CValue::setValue(double dValue, short index)
{
m_bValueInvalid = false;
bool returnValue(true);
dValue = dValue / m_nScaling;
if(index < m_sArrayEntries)
m_aValue[index] = dValue;
else
returnValue = false;
if(m_bInterpretedValue)
InterValue();
return returnValue;
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
CString CValue::getAllDataAsString()
{
CString returnValue = "";
if(!m_bValueInvalid)
{
CString temp = "";
for(short i(0); i < m_sArrayEntries; i++)
{
temp.Format("%lf", m_aValue[i]);
returnValue += temp;
}
if(m_DataClass == inter)
{
returnValue += m_sFaultInter;
temp.Format("%lf", m_nFault);
returnValue += temp;
}
}else
{
returnValue = "data corrupted";
}
return returnValue;
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------
void CValue::addFaultInterInfo(short nFault, CString sFault)
{
m_vFaultInterInfo.push_back(new CInterInfo(nFault, sFault));
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
void CValue::addValueInterInfo(double dValue, CString sValue)
{
m_vValueInterInfo.push_back(new CInterInfo(dValue, sValue));
}
//------------------------------------------------------------------------------------------------------------------------------------------------------
void CValue::deleteAllInterInfo(void)
{
std::vector<int>::size_type i = m_vFaultInterInfo.size();
if( i != 0)
for(i; i >= 0; --i)
{
if(m_vFaultInterInfo[i] != NULL)
delete m_vFaultInterInfo[i];
}
m_vFaultInterInfo.clear();
i = m_vValueInterInfo.size();
if(i != 0)
for(i; i >= 0; --i)
{
if(m_vValueInterInfo[i] != NULL)
delete m_vValueInterInfo[i];
}
m_vValueInterInfo.clear();
}
Die einzelnen Variablen definitionen:
(Hab hierbei mal die Komplexen und Geschützten Datentypen mal weggelassen...)
Code:
#pragma once
#include "var.h"
//------------------------------------------------------------------------------------------------------------------------------------------------------
class CSimpleDataType : public CVar
{
private:
public:
CSimpleDataType(void);
CSimpleDataType(CString VarName, AddrType AddrTypeOfVar, long AddressOfVar,
short Scaling, short NumberOfArrayEntries, bool bIsFloat, bool bInterpretedValue);
virtual ~CSimpleDataType(void);
};
//------------------------------------------------------------------------------------------------------------------------------------------------------
class CSchar : public CSimpleDataType
{
private:
static const short NeededBytesPerValue;
public:
CSchar();
CSchar(CString VarName, AddrType AddrTypeOfVar, long AddressOfVar, short NumberOfArrayEntries);
//~CSchar();
bool InterpretRawData(void);
};
//------------------------------------------------------------------------------------------------------------------------------------------------------
class CTBool: public CSimpleDataType
{
private:
static const short NeededBytesPerValue;
public:
CTBool();
CTBool(CString VarName, AddrType AddrTypeOfVar, long AddressOfVar, short NumberOfArrayEntries);
//~CTBool();
bool InterpretRawData(void);
};
Variablen implementierung:
Code:
#include ".\simpledatatype.h"
const short CSchar::NeededBytesPerValue = 1;
const short CSint::NeededBytesPerValue = 2;
const short CSlong::NeededBytesPerValue = 4;
const short CTBool::NeededBytesPerValue = 1;
const short CTSrBool::NeededBytesPerValue = 1;
const short CTModulation::NeededBytesPerValue = 2;
const short CUchar::NeededBytesPerValue = 1;
const short CUint::NeededBytesPerValue = 2;
const short CUlong::NeededBytesPerValue = 4;
const short CTIte::NeededBytesPerValue = 2;
const short CTState::NeededBytesPerValue = 1;
const short CNSR_Time::NeededBytesPerValue = 1;
//----------------------------------------------------------------------------------------------------------------------------------------------
//C´tor definitions
//----------------------------------------------------------------------------------------------------------------------------------------------
CSimpleDataType::CSimpleDataType(void)
{
}
//--------------------------------------------------------------------------------
CSimpleDataType::~CSimpleDataType(void)
{
delete m_Value;
}
//--------------------------------------------------------------------------------
CSimpleDataType::CSimpleDataType(CString VarName, AddrType AddrTypeOfVar, long AddressOfVar,
short Scaling, short NumberOfArrayEntries, bool bIsFloat, bool bInterpretedValue) :
CVar(VarName, AddrTypeOfVar, AddressOfVar)
{
m_Value = new CValue(simple, NumberOfArrayEntries, Scaling, bIsFloat, bInterpretedValue);
}
//--------------------------------------------------------------------------------
CSchar::CSchar(CString VarName, AddrType AddrTypeOfVar, long AddressOfVar, short NumberOfArrayEntries) :
CSimpleDataType(VarName, AddrTypeOfVar, AddressOfVar, 1, NumberOfArrayEntries, false, false)
{
}
//--------------------------------------------------------------------------------
CTBool::CTBool(CString VarName, AddrType AddrTypeOfVar, long AddressOfVar, short NumberOfArrayEntries) :
CSimpleDataType(VarName, AddrTypeOfVar, AddressOfVar, 1, NumberOfArrayEntries, false, true)
{
}
//--------------------------------------------------------------------------------
bool CTBool::InterpretRawData(void)
{
bool returnValue(false);
short neededArrayEntries = (m_Value->getNbOfArrayEntries() * NeededBytesPerValue + 1); //The device also returns the commando
short startPos = 2;
if(getAddrType() == addrSym) //Falls symbolisch, dann wird die Adresse der Variable zurück geliefert
{
neededArrayEntries += 2;
startPos += 2;
}
if(m_abRawData[0] == neededArrayEntries)
{
int receivedValue;
for(short i(0); i < m_Value->getNbOfArrayEntries(); i++)
{
receivedValue = m_abRawData[startPos + i * NeededBytesPerValue + 0];
m_Value->setValue(receivedValue, i); //The Function scales the Value!
returnValue = true;
}
}else
{
m_Value->invalidateValues();
}
return returnValue;
}
Wäre euch echt dankbar wenn sich jemand die Mühe machen würde das hier durch zu ackern und mir vielleicht sagen kann woran es liegt^^
Würd mir schon reichen wenn mir jemand sagen könnte worauf Excel mehr achtet als nen C++ Client.
Danke im Vorraus
Grüße RuFF