J
John Dumais
Hello,
I have a templated class defined in a header file and implemented in a
cpp
source file. The class is basically a little marshaler that contains a
factory method and a few marshaling functions. The template parameter
defines the type stored in a contained vector. That class is built into
a
shared library. The (condensed) code goes like this...
TypeMarshaler.h
#include <vector>
#include <string>
struct ITypeMarshaler
{
virtual void Marshal() = 0;
virtual void Unmarshal() = 0;
};
template <typename T>
class TypeMarshaler : public ITypeMarshaler
{
public:
virtual void Marshal();
virtual void Unmarshal();
private:
std::vector<T> dataValues;
};
class TypeMarshalerFactory
{
public:
static ITypeMarshaler* Create(const std::string &dataType);
};
TypeMarshaler.cpp
#include "TypeMarshaler.h"
ITypeMarshaler* TypeMarshalerFactory::Create(const std::string
&dataType)
{
// this is implemented using a map in the real code, but just so you
get
the idea...
if(dataType == "System.Int32") { return new TypeMarshaler<long>; }
... and so on
}
template <typename T>
void TypeMarshaler<T>::Marshal()
{
...
}
template <typename T>
void TypeMarshaler<T>::Unmarshal()
{
...
}
The client code looks like this and links against the shared library...
Client.cpp
#include "TypeMarshaler.h"
int main()
{
ITypeMarshaler *tm = TypeMarshalerFactory::Create("System.Int32");
... use tm & do other stuff.
return 0;
}
The client does what I expect on HP-UX 11 using aCC, Linux using gcc,
Windows using MS VC 6 & 7. However, on Sun 5.7 using whatever the most
popular Sun-supplied compiler is, linking the client results in
unresolved
externals of the form...
std::vector<long, allocator_stuff<long> >::_M_fill_insert(...) first
referenced in libTypeMarshaler.so.
I would have thought that having the TypeMarshalerFactory::Create()
method
reference a data type in a "new" expression would have been good enough
to
get the contained vector type defined in the shared library, since
client
code doesn't directly reference the TypeMarshaler type.
Am I doing something fundamentally wrong?
Thanks,
I have a templated class defined in a header file and implemented in a
cpp
source file. The class is basically a little marshaler that contains a
factory method and a few marshaling functions. The template parameter
defines the type stored in a contained vector. That class is built into
a
shared library. The (condensed) code goes like this...
TypeMarshaler.h
#include <vector>
#include <string>
struct ITypeMarshaler
{
virtual void Marshal() = 0;
virtual void Unmarshal() = 0;
};
template <typename T>
class TypeMarshaler : public ITypeMarshaler
{
public:
virtual void Marshal();
virtual void Unmarshal();
private:
std::vector<T> dataValues;
};
class TypeMarshalerFactory
{
public:
static ITypeMarshaler* Create(const std::string &dataType);
};
TypeMarshaler.cpp
#include "TypeMarshaler.h"
ITypeMarshaler* TypeMarshalerFactory::Create(const std::string
&dataType)
{
// this is implemented using a map in the real code, but just so you
get
the idea...
if(dataType == "System.Int32") { return new TypeMarshaler<long>; }
... and so on
}
template <typename T>
void TypeMarshaler<T>::Marshal()
{
...
}
template <typename T>
void TypeMarshaler<T>::Unmarshal()
{
...
}
The client code looks like this and links against the shared library...
Client.cpp
#include "TypeMarshaler.h"
int main()
{
ITypeMarshaler *tm = TypeMarshalerFactory::Create("System.Int32");
... use tm & do other stuff.
return 0;
}
The client does what I expect on HP-UX 11 using aCC, Linux using gcc,
Windows using MS VC 6 & 7. However, on Sun 5.7 using whatever the most
popular Sun-supplied compiler is, linking the client results in
unresolved
externals of the form...
std::vector<long, allocator_stuff<long> >::_M_fill_insert(...) first
referenced in libTypeMarshaler.so.
I would have thought that having the TypeMarshalerFactory::Create()
method
reference a data type in a "new" expression would have been good enough
to
get the contained vector type defined in the shared library, since
client
code doesn't directly reference the TypeMarshaler type.
Am I doing something fundamentally wrong?
Thanks,