I have been tasked to remove Rogue wave from our very old projects. I am creating wrappers around the main RW objects ( RWCString, RWCollectable, RWCRegEx, RWSet
I am having an issue with RWSet
Creating a POC from the Bus example that Rogue wave publishes in its documentation.
I am getting linker error on the >> operator. My wrapper is just a pass through wrapper.
I do not get the linker error on the << operator. If I take the >>operator ( restoreGuts ) out of the project, the project compiles and saves the data to a file ( RWFile ).
#pragma once
#ifndef __BUS_H__
#define __BUS_H__
#include <rw/rwset.h>
#include <rw/collstr.h>
#include <rw/collect.h>
#include <OptumBaseCollectable.h>
#include <OptumSet.h>
#include <rw/epersist.h>
#include <rw/edefs.h>
#define MODULE_FUNCTION
class Bus : public OptumBaseCollectable {
RW_DECLARE_COLLECTABLE_CLASS(MODULE, Bus)
//RWDECLARE_COLLECTABLE(Bus)
public:
Bus();
Bus(int busno, const RWCString& driver);
~Bus();
//OptumBaseCollectable* optBaseColl;
// Inherited from class "RWCollectable":
RWspace binaryStoreSize() const;
int compareTo(const OptumBaseCollectable*) const;
RWBoolean isEqual(const OptumBaseCollectable*) const;
unsigned hash() const;
void restoreGuts(RWFile&);
void restoreGuts(RWvistream&);
void saveGuts(RWFile&) const;
void saveGuts(RWvostream&) const;
/* RWCollectable* newSpecies() const;*/
void addPassenger(const char* name);
void addCustomer(const char* name);
size_t customers() const;
size_t passengers() const;
RWCString driver() const {return driver_;}
int number() const {return busNumber_;}
inline friend RWFile& operator>>(RWFile& f, OptumSet*& pCl);
//RWvistream& operator>>(RWvistream& vstream, const Bus* p);
private:
OptumSet * customers_;
OptumSet * passengers_;
int busNumber_;
RWCString driver_;
};
RWDECLARE_PERSISTABLE(Bus)
class Client : public RWCollectable {
RWDECLARE_COLLECTABLE(Client)
Client();
Client(const char* name);
RWspace binaryStoreSize() const;
int compareTo(const RWCollectable*) const;
RWBoolean isEqual(const RWCollectable*) const;
unsigned hash() const;
void restoreGuts(RWFile&);
void restoreGuts(RWvistream&);
void saveGuts(RWFile&) const;
void saveGuts(RWvostream&) const;
private:
RWCString name_;
//ignore other client information for this example
};
#endif
Bus.cpp
#include "StdAfx.h"
#include "bus.h"
#include <rw/pstream.h>
#include <rw/rwfile.h>
#include <rw/epersist.h>
#ifdef __GLOCK__
#include <fstream.hxx>
#else
#include <fstream>
#endif
RW_DEFINE_COLLECTABLE_CLASS_BY_ID(MODULE, Bus,100)
Bus::Bus() :
busNumber_ (0),
driver_ ("Unknown"),
passengers_ (rwnil)
{
//optBaseColl = new OptumBaseCollectable();
}
Bus::Bus(int busno, const RWCString& driver) :
busNumber_ (busno),
driver_ (driver),
passengers_ (rwnil)
{
customers_ = new OptumSet(64);
}
Bus::~Bus() {
customers_->clearAndDestroy();
delete passengers_;
delete customers_;
}
RWspace
Bus::binaryStoreSize() const {
RWspace count = RWCollectable::binaryStoreSize() +
customers_->recursiveStoreSize() +
sizeof(busNumber_) +
driver_.binaryStoreSize();
if (passengers_)
count += passengers_->recursiveStoreSize();
else
count += nilStoreSize();
return count;
}
int
Bus::compareTo(const OptumBaseCollectable* c) const {
const Bus* b = (const Bus*)c;
if (busNumber_ == b->busNumber_) return 0;
return busNumber_ > b->busNumber_ ? 1 : -1;
}
RWBoolean
Bus::isEqual(const OptumBaseCollectable* c) const {
const Bus* b = (const Bus*)c;
return busNumber_ == b->busNumber_;
}
unsigned
Bus::hash() const {
return (unsigned)busNumber_;
}
size_t
Bus::customers() const {
return customers_->entries();
}
size_t
Bus::passengers() const{ return passengers_ ? passengers_->entries() : 0;
}
void
Bus::saveGuts(RWFile& f) const {
OptumBaseCollectable::saveGuts(f); // Save base class
f.Write(busNumber_); // Write primitive directly
f << driver_ << customers_; // Use Rogue Wave provided versions
f << passengers_; // Will detect nil pointer automatically
}
void
Bus::saveGuts(RWvostream& strm) const {
OptumBaseCollectable::saveGuts(strm); // Save base class
strm << busNumber_; // Write primitives directly
strm << driver_ << customers_; // Use Rogue Wave
// provided versions
strm << passengers_; // Will detect nil pointer automatically
}
void Bus::restoreGuts(RWFile& f) {
OptumBaseCollectable::restoreGuts(f); // Restore base class
f.Read(busNumber_); // Restore primitive
f >> driver_ >> customers_; // Uses Rogue Wave
// provided versions
delete passengers_; // Delete old RWSet
f >> passengers_; // Replace with a new one
}
void Bus::restoreGuts(RWvistream& strm) {
RWCollectable::restoreGuts(strm); // Restore base class
strm >> busNumber_ >> driver_ >> customers_;
delete passengers_; // Delete old RWSet
strm >> (RWCollection&)passengers_; // Replace with a new one
}
void
Bus::addPassenger(const char* name) {
Client* s = new Client(name);
customers_->insert( s );
if (!passengers_)
passengers_ = new OptumSet(64);
passengers_->insert(s);
}
void
Bus::addCustomer(const char* name) {
customers_->insert( new Client(name) );
}
/////////////// Here are Client methods //////////////
RWDEFINE_NAMED_COLLECTABLE(Client,"client")
Client::Client() {} // Uses RWCString default constructor
Client::Client(const char* name) : name_(name) {}
RWspace
Client::binaryStoreSize() const {
return name_.binaryStoreSize();
}
int
Client::compareTo(const RWCollectable* c) const {
return name_.compareTo(((Client*)c)->name_);
}
RWBoolean
Client::isEqual(const RWCollectable* c) const {
return name_ == *((Client*)c)->name_;
}
unsigned
Client::hash() const {
return name_.hash();
}
void
Client::restoreGuts(RWFile& f) {
f >> name_;
}
void
Client::restoreGuts(RWvistream& vis) {
vis >> name_;
}
void
Client::saveGuts(RWFile& f) const {
f << name_;
}
void
Client::saveGuts(RWvostream& vos) const {
vos << name_;
}
#ifndef _OPTUMSET_H
#define _OPTUMSET_H
#include <rw\rwset.h>
#define MODULE_FUNCTION
class __declspec(dllexport) OptumSet : public RWSet
{
RW_DECLARE_COLLECTABLE_CLASS(MODULE, OptumSet)
//RWDECLARE_COLLECTABLE(OptumSet)
public:
OptumSet (size_t n = RWDEFAULT_CAPACITY);
OptumSet (const OptumSet & h);
virtual ~OptumSet();
};
#endif
OptumSet.CPP
#include <OptumSet.h>
RW_DEFINE_COLLECTABLE_CLASS_BY_ID(MODULE, OptumSet,50)
//RWDEFINE_COLLECTABLE(OptumSet, 100)
OptumSet::OptumSet(size_t n)
{
std::string mystr = "mystr";
}
OptumSet::~OptumSet()
{
}
OptumSet::OptumSet (const OptumSet & h) : RWSet(h)
{
std::string mystr = "mystr";
}
Again, OptumSet is intended as a pass through class. I have tried every combination of the Declare and Defines that RW includes in their .h files.
Error 13 error LNK2019: unresolved external symbol "class RWFile & __cdecl operator>>(class RWFile &,class OptumSet * &)" (??5@YAAAVRWFile@@AAV0@AAPAVOptumSet@@@Z) referenced in function "public: virtual void __thiscall Bus::restoreGuts(class RWFile &)" (?restoreGuts@Bus@@UAEXAAVRWFile@@@Z) C:\Carol\Projects\RWCollectionPOC\Bus.obj RWCollectionPOC
I am expecting to use the documented public >> RW method of class RWFile &, Class *&). It isn't virtual so I can't override it. It is public so I am trying to just pass through to the RWCollectable which has the >> method and is the very base of RWSet.
If you are interested in the whole POC, let me know I can provide it.
Thanks in advance
This isn't a duplicate. This has to do more with the Roguewave implementation then the linker error. I know I am missing something, but I don't know what it is. If I add the declaration of >> then I will get that it is already defined. So I am pretty confused.