Why doesn't Xcode recognize free() and malloc() in this .cpp file? - c++

I have many .cpp files in my project that work. But this one irritates Xcode or the compiler.
It doesn't recognise free() and malloc() but this is also C. What can be wrong?
Header ssdpmessage.h looks like this:
#ifndef _SSDPMESSAGE_H
#define _SSDPMESSAGE_H
#include "ssdptools.h"
#include <vector>
#include <arpa/inet.h>
#include "ssdpdb.h"
class SSDPMessage{
public:
SSDPMessage();
virtual ~SSDPMessage();
//What type of message can we handle
virtual SSDP_TYPE GetType()=0;
//Get the message dignature implemented in this class
virtual std::vector<SSDP_HTTP_HEADER*> GetHeaderSignature();
//Can this class parse the message with this signature ?
virtual u8 CanProcess(std::vector<SSDP_HTTP_HEADER*> msgheaders);
//Process the message, return value:
//0 : processed
//1 : not for me, search for another to process
//<0 : message was for me but there is an error
virtual int Process(struct sockaddr* sender, std::vector<SSDP_HTTP_HEADER*> msgheaders)=0;
//ReInit all members
virtual void ReInit()=0;
virtual SSDPDB* GetDB();
virtual void SetDB(SSDPDB* db);
private:
std::vector<SSDP_HTTP_HEADER*> mHeaderSignature;
protected:
int AddSignatureHeader(char* fieldname, char* fieldvalue);
SSDPDB *mDB;
private:
SSDPMessage(const SSDPMessage &src);
SSDPMessage& operator= (const SSDPMessage &src);
};
#endif //_SSDPMESSAGE_H
The includes and affected code in ssdpmessage.cpp look like this:
#include "ssdpmessage.h"
SSDPMessage::SSDPMessage():mDB(NULL){
}
SSDPMessage::~SSDPMessage(){
std::vector<SSDP_HTTP_HEADER*>::iterator it;
for(it=mHeaderSignature.begin(); it<mHeaderSignature.end(); it++){
free(*it);
}
mHeaderSignature.clear();
}
int SSDPMessage::AddSignatureHeader(char* fieldname, char* fieldvalue){
SSDP_HTTP_HEADER *thisHeader = (SSDP_HTTP_HEADER*)malloc(sizeof(SSDP_HTTP_HEADER));
thisHeader->fieldname = (u8*)fieldname;
thisHeader->fieldnamelen = strlen(fieldname);
thisHeader->fieldvalue = (u8*)fieldvalue;
thisHeader->fieldvaluelen = strlen(fieldvalue);
mHeaderSignature.push_back(thisHeader);
return mHeaderSignature.size();
}
This is code from the upnpx library. It works without problem in the demo project of the library.

malloc requires you to include cstdlib.

Related

C++ using member functions with forward declaration

I've seen similar questions, but not quite like the predicament I find myself in. I'm working with someone else's code, and their structure is like this.
//db_manager.h
class db_manager
{
class error;
bool logError(error::def_enum::Value v, string msg);
bool read(int id);
}
//db_manager.cpp
#include db_manager.h
bool logError(error::def_enum::Value v, string msg)
{
return error::logError(v, msg);
}
bool read(int id)
{
//do db access stuff
return true;
}
//error.h
#include db_manager
class error
{
bool read(int id);
}
//error.cpp
#include error.h
bool read(int id)
{
return db_manager::read(id);
}
bool logError(error::def_enum::Value v, string msg)
{
//do error service stuff
}
This is a pretty obvious simplification, but hopefully it demonstrates the issue.
When I compile, I get a lot of incomplete type errors whenever error is used in db_manager.cpp, and I can't include the relevant header files from error into db_manager.cpp, because then I have to add it to db_managers cmake dependencies, which means I have to list it in package.xml, and then it gets upset from the circular dependency. How can I get around this? If I could use error's members in db_manager without making error a dependency, I'd be good, I think, but I just can't figure out how to do that. I've seen many other forward-declaration questions on here, but for all of them, the declared class usage isn't very deep. Here I'm using class members, not just declaring a class pointer like other questions.
I definitely could use help, I just don't see any logical way to do this without completely scrapping the error package and writing a new one.
Edit: also, I simplified this out, but maybe I shouldn't have. error and db_manager are in two separate packages.
First: Your example is very bad. Please provide a minimum working example. I understand what your problem is (circular dependency), but your example is not showing this Problem. This is something you have to solve on an architectural level. You can't solve this inside CMake.
Depending on the Code you have shown you don't need to include db_manager.h in error.h, since you are not using anything from db_manager during the declaration of class Error. You only need to include it inside error.cpp, since there you are using one static method from db_manager. That way you don't have any circular dependency.
I have added a minimum working example below which compiles without any errors.
error.h
#ifndef _ERROR_H_
#define _ERROR_H_
#include <string>
class Error
{
public:
enum def_enum{ Val1, Val2};
bool read(int id);
static bool logError(def_enum v, std::string msg);
};
#endif /* _ERROR_H_ */
error.cpp
#include "error.h"
#include "db_manager.h"
bool Error::read(int id)
{
return db_manager::read(id);
}
bool Error::logError(Error::def_enum v, std::string msg)
{
//do error service stuff
return true;
}
db_manager.h
#ifndef _DB_MANAGER_H_
#define _DB_MANAGER_H_
#include <string>
#include "error.h"
class db_manager
{
public:
static bool logError(Error::def_enum v, std::string msg);
static bool read(int id);
};
#endif /* _DB_MANAGER_H_ */
db_manager.cpp
#include "db_manager.h"
bool db_manager::logError(Error::def_enum v, std::string msg)
{
return Error::logError(v, msg);
}
bool db_manager::read(int id)
{
//do db access stuff
return true;
}
main.cpp
#include "db_manager.h"
#include "error.h"
int main(){
db_manager::read(1);
db_manager::logError(Error::Val1, "Test");
Error e;
e.read(2);
return 0;
}
CMakeLists.txt
project(db_manager)
add_executable(executable main.cpp db_manager.cpp error.cpp)

unique_ptr<> causes compliation errors in C++

I am using this library: https://github.com/Agamnentzar/bluetooth-serial-port
BTSerialPortBinding::Create(address, channelID)
Returns new instance of BTSerialPortBinding object
address: string containint bluetooth address of the device
channelID: ID of the serial port channel
I have a statement:
unique_ptr<BTSerialPortBinding>bt(BTSerialPortBinding::Create(d1.address, 1));
When I separate the statement with the declaration in ArduinoDevice.h and initialisation in ArduinoDevice.cpp in constructor like so:
std::unique_ptr<BTSerialPortBinding> bt;
bt.reset(BTSerialPortBinding::Create("93:83:, 1));
When I added these statements I got the following error:
ArduinoDevice &ArduinoDevice::operator =(const ArduinoDevice &)': attempting to reference a deleted function
Relevant bit in Process.cpp file which is referenced by the error
dev = ArduinoDevice("/dev/tty.IP-DevB");
Process.h
#ifndef __PROCESS_H
#define __PROCESS_H
#define _USE_MATH_DEFINES
#include "ResonantLowpassFilter.h"
#include "ArduinoDevice.h"
//==============================================================================
/**
*/
class AudioProcessor : public AudioProcessor
{
public:
//==============================================================================
WahwahAudioProcessor();
~WahwahAudioProcessor();
void prepareToPlay (double sampleRate, int samplesPerBlock);
void releaseResources();
void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages);
AudioProcessorEditor* createEditor();
int getNumParameters();
int getNumPrograms();
int getCurrentProgram();
void setCurrentProgram (int index);
const String getProgramName (int index);
void changeProgramName (int index, const String& newName);
float centreFrequency_, q_;
void updateFilterArduino();
ArduinoDevice dev; //instance to an Arduino device from which sensor data is read
};
#endif // _PROCESS
ArduinoDevice.h
#ifndef ArduinoDevice_h
#define ArduinoDevice_h
#include <stdio.h>
#include "BTSerialPortBinding.h"
#include <memory>
class ArduinoDevice
{
public:
ArduinoDevice(const char *dev="");
void connect();
void start(void);
void stop(void);
void read(void);
/**
Disconnects from Arduino device
**/
~ArduinoDevice();
private:
const char *device; //port address of the device (e.g. "/dev/tty.FireFly-E552-SPP")
std::unique_ptr<BTSerialPortBinding> bt; //bt serial port
void close(void);
};
#endif
Edit:
I am using Windows 10, Visual Studio 2015 and Microsoft's C++ Compiler. I am also using an extra JUCE library(https://www.juce.com/).
dev = ArduinoDevice("/dev/tty.IP-DevB"));
dev is declared in the Process.h file above its an instance of ArduinoDevice
My constructor looks like this:
ArduinoDevice::ArduinoDevice(const char *dev)
{
device = dev;
bt.reset(BTSerialPortBinding::Create("98:D3:31:FD:11:1A", 1));
}
I've now tried this in ArduinoDevice.cpp and declaration .h but I still get the same error as above:
ArduinoDevice&&(const char *dev);
{
data = dev.data;
dev.data = nullptr;
}
unique_ptr is not copyable. So when you declare it as a member of your class, your class becomes non-copyable too. The error exactly points that out. (Copy assignment operator is deleted because of that).
Note that usually the move assignment operator is automatically generated by the compiler for you. But in your case since you've explicitly defined a destructor for your class, compiler cant safely define a move assignment operator (or constructor) for you.

Accessing Methods in Declaration vs Implementation

I'm having difficulty interpreting some of my results, which I would expect to behave the same but are not.
I am trying to write a method that returns a function pointer getPtrFn
I have a main.c file reading
#include <iostream>
#include "test.hpp"
int main(int argc, char* argv[]){
Test test;
void (*fPtr)(void) = test.getPtrFn();
return 0;
}
A test.hpp file that reads
#ifndef _test_h
#define _test_h
class Test {
private:
void (*ptrFn)(void);
public:
Test(){};
void (*getPtrFn(void))(void){
return ptrFn;
};
~Test();
};
#endif
And a test.cpp file that reads
#include "test.hpp"
Test::~Test(){}
This runs fine. However, when I move the implementation for *getPtrFn(void) to the implementation file (revised files shown below),
test.hpp:
#ifndef _test_h
#define _test_h
class Test {
private:
void (*ptrFn)(void);
public:
Test(){};
void (*getPtrFn(void))(void);
~Test();
};
#endif
test.cpp:
#include "test.hpp"
void (Test::*getPtrFn)(void){
return ptrFn;
};
Test::~Test(){}
I get the compile error
test.cpp:16:9: error: use of undeclared identifier 'ptrFn'
My understanding of the language syntax is that they would be treated the same. So what gives?
-Jeff
You need
void(*Test::getPtrFn(void))(void)
{
return ptrFn;
}
instead of void (Test::*getPtrFn)(void){...}. void (Test::*getPtrFn)(void) is the declaration of getPtrFn as a pointer-to-Test-member-function taking no parameters (void) and returning void, so after you put the braces { ... } you get a compile-time error (its like trying to declare int i{/*some statemets*/}).
Also, and don't forget to keep the declaration
void(*getPtrFn(void))(void);
in your header (right now it seems you don't have it, did you cut/pasted it?).
Quite a horrible thing to look at... So really, use a type alias, it makes your code much cleaner.
using PTRFN = void(*)(void); // or typedef void(*PTRFN)(void);
class Test {
private:
PTRFN ptrFn;
public:
PTRFN getPtrFn(void);
Test(){};
~Test(){};
};
PTRFN Test::getPtrFn(void) // clear an concise
{
return ptrFn;
}
In case you really really want to be able do decipher every kind of pointer declaration you can think of, try looking at the clockwise/spiral rule, I found it extremely useful, clear and easy to understand. Then test your knowledge at cdecl.org.

“Class type redefinition” error between header and source files (Different Case)

I have seen this question: "Class type redefinition" error between header and source files
If you'll just say a duplicate of the above question, please check first the code below.
The problem is that the "Class type redefinition" should not happened because I think I have done it properly.
Here is the code.
TTSpeech.h
#include <wtypes.h>
#include <string>
#include <vector>
class TTSpeech
{
public:
enum State
{
State_Loaded,
State_Unloaded,
};
TTSpeech();
virtual ~TTSpeech();
virtual bool isAvailable() = 0;
virtual bool load() = 0;
virtual bool unload() = 0;
virtual bool isLoaded() const = 0;
virtual bool say(const std::string &sentence) = 0;
virtual bool setVolume(int volume) = 0;
virtual bool setPitch(int pitch) = 0;
virtual bool setRate(int rate) = 0;
virtual bool setVoice(const std::string &voice) = 0;
virtual std::vector<std::string> getVoices() const = 0;
};
TTSpeech.cpp
#include "TTSpeech.h"
TTSpeech::TTSpeech()
{
//code
}
TTSpeech::~TTSpeech()
{
//code
}
The only unusual thing that I have done is to remove the files from the solution, relocate the above file to a folder because of this issue: cannot open include no such file or directory. Then re-add the files to the solution. I'm using Visual Studio 2012 running of Windows 8

What is the right way to return a reference to a class static data member? (I'm using Qt, in case it makes a difference)

I'm trying to get the address of a class static data member from a DLL and keep it around in host code. However, I'm loosing the pointer / reference to the member the minute I exit the method in the dll-manager which opens all the (Windows typedef) HINSTANCE s, even though I'm keeping them open.
My setup is:
A Qt GUI application, which includes a class that loads plugins from dlls. This dll-manager class doesn't use Qt stuff but for Qdir and Qstrings here and there...
The dll-manager should issue a bunch of LoadLibrary() calls to open DLLs and for each, call an exported function which returns the address of a static "info" struct inside the class the DLL exports.
For instance, The DLL class looks like this:
BlackNWhite.h
#ifdef BLACKNWHITE_EXPORTS
#define BLACKNWHITE_API __declspec(dllexport)
#else
#define BLACKNWHITE_API __declspec(dllimport)
#endif
// This class is exported from the BlackNWhite.dll
class BLACKNWHITE_API CBlackNWhite : PCOperatorBase
{
public:
CBlackNWhite(void);
virtual ~CBlackNWhite(void);
virtual int process(int* inBuffer, int* outBuffer, int bufferSize);
void getParametersInfo(const std::vector<ParameterDescriptor>*& outParameters);
static const OperatorInfo& info();
protected:
static OperatorInfo operatorInfo;
};
extern "C" __declspec(dllexport) PCOperatorBase* getOperatorInstance();
extern "C" __declspec(dllexport) const PCOperatorBase::OperatorInfo& getOperatorInfo();
BlackNWhite.cpp
#include "stdafx.h"
#include "BlackNWhite.h"
PCOperatorBase::OperatorInfo CBlackNWhite::operatorInfo = {L"Black N White", L"modifier", L"color"};
const PCOperatorBase::OperatorInfo& CBlackNWhite::info()
{
return CBlackNWhite::operatorInfo;
}
extern "C" __declspec(dllexport) PCOperatorBase* getOperatorInstance()
{
return (PCOperatorBase*)(new CBlackNWhite());
}
extern "C" __declspec(dllexport) const PCOperatorBase::OperatorInfo& getOperatorInfo()
{
return CBlackNWhite::info();
}
CBlackNWhite::CBlackNWhite()
: PCOperatorBase()
{
ParameterDescriptor newParameter;
newParameter.label = L"Parameter 1";
parameters.push_back(newParameter);
}
CBlackNWhite::~CBlackNWhite()
{
}
int CBlackNWhite::process(int* inBuffer, int* outBuffer, int bufferSize)
{
while(bufferSize--)
*outBuffer++ = *inBuffer++;
return 0;
}
void CBlackNWhite::getParametersInfo(const std::vector<ParameterDescriptor>*& outParameters)
{
outParameters = &parameters;
}
And this class inherits from a base class:
PCOperatorBase.h
#pragma once
#include "PCOperatorParameters.h"
#include <vector>
class PCOperatorBase
{
public:
typedef struct OperatorInfo
{
wchar_t* name;
wchar_t* type;
wchar_t* subtype;
} OperatorInfo;
PCOperatorBase(void){};
virtual ~PCOperatorBase(void){};
virtual void getParametersInfo(const std::vector<ParameterDescriptor>*& outParameters) = 0;
virtual int process(int* inBuffer, int* outBuffer, int bufferSize) = 0;
protected:
std::vector<ParameterDescriptor>parameters;
};
And the DLL-manager has two relevant methods. One builds the list of available plugins and the other one just returns the string names of the plugins.
void PCOperatorManager::buildOperatorList(const QString path)
{
QDir operatorDirectory(QDir::currentPath() + path);
if(operatorList.size())
operatorList.clear();
QStringList operatorNameList = operatorDirectory.entryList(QStringList("*.dll"));
typedef PCOperatorBase::OperatorInfo*(*PCOClassInfoFunction)();
for(QStringList::iterator PCOClassName = operatorNameList.begin();
PCOClassName != operatorNameList.end();
PCOClassName++)
{
HINSTANCE PCOClassHandle;
if((PCOClassHandle = LoadLibrary((operatorDirectory.absolutePath() + "/"+ *PCOClassName).toStdWString().c_str())))
{
OperatorDescriptor newPCOClassDescriptor;
newPCOClassDescriptor.handle = PCOClassHandle;
newPCOClassDescriptor.info = (*((PCOClassInfoFunction)GetProcAddress(PCOClassHandle, "getOperatorInfo")))();
operatorList.push_back(newPCOClassDescriptor);
printf("\n we have: %ls", operatorList[0].info->name);
}
}
}
QStringList PCOperatorManager::getOperatorNameList()
{
QStringList operatorNameList;
printf("\n the list length is: %i", operatorList.size());
for(int i = 0; i < operatorList.size(); i++)
printf("\n we have again: %ls", operatorList[0].info->name);
//operatorNameList << QString::fromWCharArray((*PCOClass).info.name);
return operatorNameList;
}
What's happening is: inside buildOperatorList() I can access the static member of the DLL-class and assign it to the info member in the OperatorDescriptor struct. That is, the "test" printf statement that reads "we have" does print out the right value for that field.
However, inside getOperatorNameList() the info member is not valid anymore.
My line of thought is that what I'm doing is:
I have a pointer to a OperatorInfo struct, called info.
I get the address of a static OperatorInfo struct in the DLL-class,
called operatorInfo.
I assign the address of the class' operatorInfo to the pointer
called info. That is info = &CBlackNWhite::operatorInfo;
At this point, the pointer should stay valid as long as I don't issue a FreeLibrary() on the DLL HINSTANCE
So what's going on?
I see here operatorList is not a member variable of PCOperatorManager once it is added and constructed as in buildOperatorList I think you should ave access in getOperatorNameList()