[!! RANT !!] This is a hack at best (C4251)

A

Alfonso Morra

I cannot believe how convoluted it is to export function templates and
class templates from a shared library (or DLL as it is called in the
Windoze world).

Micro$oft support for STL and standards in general is absolutely
appaling. This is absolutely ridiculous. I have obtaind links from
people who tried to help me solve this problem, several days ago, to no
avail. Even the sample code at http://support.microsoft.com/kb/q168958/
when adapted to my code (i.e. #defines specified etc), still generates
compiler errors like:

error C2757: 'std' : a symbol with this name already exists and
therefore this name cannot be used as a namespace name

This is from code provided by Microsoft. I TRULY HATE Microsoft (there I
said it), and their non-standard, proprietary way of doing everything.
I would not touch their flaky compilers if I did not have to work with
them ...Arghhhh, I'm going out for a cofee break !
 
B

Bruno van Dooren

firstly, the latest microsoft compiler is more standards compliant than gcc,
or most other compilers. gcc is about the worst when ot comes to standards
compliance.

secondly, AFAIK, template code is handled by the preprocessor in some sort
of copy and paste action to generate the correct code. it only makes sense
that you cannot export raw templates from binary code. gcc does not allow
you to do this.

third: things like Micro$oft and Windoze do not make you funny. I do not
talk about LinSucks either, and btw, do you think that IBM is on the linux
train because they are huggy feeling types?
 
P

Peter van der Goes

Alfonso Morra said:
I cannot believe how convoluted it is to export function templates and
class templates from a shared library (or DLL as it is called in the
Windoze world).

Micro$oft support for STL and standards in general is absolutely appaling.
This is absolutely ridiculous. I have obtaind links from people who tried
to help me solve this problem, several days ago, to no avail. Even the
sample code at http://support.microsoft.com/kb/q168958/ when adapted to my
code (i.e. #defines specified etc), still generates compiler errors like:

error C2757: 'std' : a symbol with this name already exists and therefore
this name cannot be used as a namespace name

This is from code provided by Microsoft. I TRULY HATE Microsoft (there I
said it), and their non-standard, proprietary way of doing everything. I
would not touch their flaky compilers if I did not have to work with them
...Arghhhh, I'm going out for a cofee break !
Perhaps when you return from your break, you'll provide some amplifying
information about the problem you are having? That might make it possible
for someone here to help you.
 
A

Alfonso Morra

Peter said:
Perhaps when you return from your break, you'll provide some amplifying
information about the problem you are having? That might make it possible
for someone here to help you.

Hi peter,

Thanks for offering to help. This is really driving me round the bend. I
have a little sample code below, which compiles and builds (with
warnings). The built DLL exports the symbols, so I am not sure why the
compiler issues the warnings (however, I have not tried to use the built
DLL).

Here is the code:


using std::string ;
using std::vector ;

#ifdef TESTDLL_EXPORTS
#define CCONV __declspec(dllexport)
#else
#define CCONV __declspec(dllimport)
#endif

class CCONV MyClass {
public :
MyClass():m_name("test"),val(0){} ;
~MyClass(){} ;

inline string getName( void ){ return m_name ; }
inline void setName( string new_name ) { this->m_name = new_name ; }

template <class T1, class T2>
void foo( T1 arg1, T2 arg2 ) {
;//dummy
};

inline vector<int> getDates( void ){ return dates ; }

private:
//prevent copy and assignment
MyClass( const MyClass& ) ;
MyClass& operator=(const MyClass&) ;

/* Nested class */
class MyNestEgg {
friend class MyClass ;
void doThis(void){;}
void doThat(void){;}
};

string m_name ;
int val ;
MyNestEgg m_nuts ;
vector<int> dates ;

public:
inline void doThisToMyNestEgg( void ) { m_nuts.doThis() ; }
inline void doThatToMyNestEgg( void ) { m_nuts.doThis() ; }

};



Two thing I must mentioned however, are:

1). I notice that the compiler does not complain about the myNestEgg
variable. In my actual code, the compile complains as ff:
"warning C4251: 'A::m_props' : class 'A::properties' needs to have
dll-interface to be used by clients of class 'A'

2). The function template is completely ignored and not even exported.
This is not too suprising since it may require template specialiazation
- but this is only a guess, siince I cannot find anything useful on
Microsoft's site - and the code given there to allow exporting STL
objects from a shlib does not work.


I hope you can provide a fix as to how to get this to work (i.e. compile
without warnings and to export STL classes). The actual code I have
inherits from a template class like this:

MyClass: public Singleton<MyClass> { ...}

For now, i want to keep things simple, and I will discuss that once I
have managed to get the simple class (i.e. with no inheritance
extensions) to compile and export symbols correctly.

MTIA
 
N

Nishant Sivakumar

The template function won't be generated until it's instantiated. So, you
really cannot export template functions from a DLL. The right way to use
templates is via a header file.

Or you could use the below technique (quite ugly I might add) :-

e.g. :-

template<typename T> void foo(T t) {...}


//export the below functions

void fooint(int t)
{
foo<int>(t);
}

void foochar(char t)
{
foo<char>(t);
}

void fooCWnd(CWnd t)
{
foo<CWnd>(t);
}

etc . . .

Export functions for every possible template specialization that the calling
code might need.

But again, the right way to do this is to include the header file defining
the template function in your calling project.
 
N

Nishant Sivakumar

Also see http://support.microsoft.com/default.aspx?scid=kb;EN-US;168958

--
Regards,
Nish [VC++ MVP]
http://www.voidnish.com
http://blog.voidnish.com


Nishant Sivakumar said:
The template function won't be generated until it's instantiated. So, you
really cannot export template functions from a DLL. The right way to use
templates is via a header file.

Or you could use the below technique (quite ugly I might add) :-

e.g. :-

template<typename T> void foo(T t) {...}


//export the below functions

void fooint(int t)
{
foo<int>(t);
}

void foochar(char t)
{
foo<char>(t);
}

void fooCWnd(CWnd t)
{
foo<CWnd>(t);
}

etc . . .

Export functions for every possible template specialization that the
calling code might need.

But again, the right way to do this is to include the header file defining
the template function in your calling project.

--
Regards,
Nish [VC++ MVP]
http://www.voidnish.com
http://blog.voidnish.com


Alfonso Morra said:
Hi peter,

Thanks for offering to help. This is really driving me round the bend. I
have a little sample code below, which compiles and builds (with
warnings). The built DLL exports the symbols, so I am not sure why the
compiler issues the warnings (however, I have not tried to use the built
DLL).

Here is the code:


using std::string ;
using std::vector ;

#ifdef TESTDLL_EXPORTS
#define CCONV __declspec(dllexport)
#else
#define CCONV __declspec(dllimport)
#endif

class CCONV MyClass {
public :
MyClass():m_name("test"),val(0){} ;
~MyClass(){} ;

inline string getName( void ){ return m_name ; }
inline void setName( string new_name ) { this->m_name = new_name ; }

template <class T1, class T2>
void foo( T1 arg1, T2 arg2 ) {
;//dummy
};

inline vector<int> getDates( void ){ return dates ; }

private:
//prevent copy and assignment
MyClass( const MyClass& ) ;
MyClass& operator=(const MyClass&) ;

/* Nested class */
class MyNestEgg {
friend class MyClass ;
void doThis(void){;}
void doThat(void){;}
};

string m_name ;
int val ;
MyNestEgg m_nuts ;
vector<int> dates ;

public:
inline void doThisToMyNestEgg( void ) { m_nuts.doThis() ; }
inline void doThatToMyNestEgg( void ) { m_nuts.doThis() ; }

};



Two thing I must mentioned however, are:

1). I notice that the compiler does not complain about the myNestEgg
variable. In my actual code, the compile complains as ff:
"warning C4251: 'A::m_props' : class 'A::properties' needs to have
dll-interface to be used by clients of class 'A'

2). The function template is completely ignored and not even exported.
This is not too suprising since it may require template specialiazation -
but this is only a guess, siince I cannot find anything useful on
Microsoft's site - and the code given there to allow exporting STL
objects from a shlib does not work.


I hope you can provide a fix as to how to get this to work (i.e. compile
without warnings and to export STL classes). The actual code I have
inherits from a template class like this:

MyClass: public Singleton<MyClass> { ...}

For now, i want to keep things simple, and I will discuss that once I
have managed to get the simple class (i.e. with no inheritance
extensions) to compile and export symbols correctly.

MTIA
 
T

Tom Widmer [VC++ MVP]

Bruno said:
firstly, the latest microsoft compiler is more standards compliant than gcc,
or most other compilers. gcc is about the worst when ot comes to standards
compliance.

GCC 4.0 is more compilant than VC8 as far as I know (it has two phase
name lookup for a start). GCC implements everything except export,
whereas VC implements everything except export, two phase name lookup,
and a few other features. See
http://msdn2.microsoft.com/library/x84h5b78(en-us,vs.80).aspx for VC
problems and this much shorter list or compliance issues for GCC:
http://gcc.gnu.org/bugs.html#known
secondly, AFAIK, template code is handled by the preprocessor in some sort
of copy and paste action to generate the correct code.

Templates are handled by the compiler, not the preprocessor, but they
can't be fully compiled until instantiation time.

Tom
 
B

Bruno van Dooren

Tom Widmer said:
GCC 4.0 is more compilant than VC8 as far as I know (it has two phase name
lookup for a start). GCC implements everything except export, whereas VC
implements everything except export, two phase name lookup, and a few
other features. See
http://msdn2.microsoft.com/library/x84h5b78(en-us,vs.80).aspx for VC
problems and this much shorter list or compliance issues for GCC:
http://gcc.gnu.org/bugs.html#known
i have not yet looked at gcc 4.0, but i knew my statements to be true for
gcc 3.0
Templates are handled by the compiler, not the preprocessor, but they
can't be fully compiled until instantiation time.
didn't know that. thanks.
 
Top