Solved

__declspec( dllexport ) with template

Posted on 1997-11-06
15
3,218 Views
Last Modified: 2008-03-10
I write a program that contains class and struct , the class
is a template class , when I export my class and struct
as dllexports , I get an warning that I can't shake , the warning go away if I declare T* t as public data , this
is the code and the explanation , the warning is shown as comment

#include <windows.h>

template <class __declspec( dllexport )       T> class __declspec( dllexport )      CClass
{
      protected :

            T*      __declspec( dllexport )            t;      // when this is declared as public data , there is no problem      

      public :

            int                  p;
};


struct __declspec( dllexport ) s1
{
      int                  a;
      int                  b;
};

struct __declspec( dllexport ) s2
{
      int                  a;
      int                  b;
      CClass<s1>      c; // this yields warning : class 'CClass<struct s1>' needs to have dll-interface to be used by clients of struct 's2'
};

class __declspec( dllexport ) s3
{
      public :

            int            a;
                        s3();
                        ~s3();
            void      go();
};



int PASCAL WinMain(  HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszCmdLine,
                     int nCmdShow)
{


      return TRUE;

}
0
Comment
Question by:moshem
  • 8
  • 7
15 Comments
 
LVL 22

Expert Comment

by:nietod
ID: 1172663
I have never seen "__declspec(dllexport" used the way you are using it.  Either you know something I don't or that might be your problem.

I've seen it used when declaring a class like

class __declspec( dllexport ) s1
{
   int a;
};

but I've never seen is for a member declaration like

CClass
{
    T* __declspec( dllexport ) t;
};

also I've never seen it in a template declaration in either of the uses you have, like

template <class __declspec( dllexport ) T>
class __declspec(dllexport ) CClass
{
};

Besides how can a template class be DLL exportable?  The DLL could export the template only for specific types.  It can't export it for all types, it does not "know" what types will be needed by EXE's and other DLL's that use it.
0
 
LVL 1

Author Comment

by:moshem
ID: 1172664
those wierd things you mentioned are testing I did to elimanate any forgoten declaration , in any case I can't bring this
code to compile without an dll export warning, I don't need the
template to be expotable but the class created via the template
can you help ?
0
 
LVL 22

Accepted Solution

by:
nietod earned 150 total points
ID: 1172665
No.  Template classes can't be exportable.  How could they be?  The DLL can't know at compile time what it will be linked to at run-time.  The EXE's and DLL's it is linked to could use the template class for classes that the DLL did not instantiate the template for.

For example say you write a swap template function that switches two of something i.e.

template<class T>
swap(T a,T b)
{
 T c = a;

 a = b;
 b = c;
};

The DLL could provide exports of the swap function for different types, like int, char, double.  But it could not provide exports for ALL types.  An EXE might try

class myclass
{
};

myclass A;
myclass B;

swap(A,B);

How could the DLL know at compile time that this version of swap would be needed at run-time?  It is theoretically possible to create code to impliment the procedure for any type (it would be pretty easy in this case) but I doubt any implimentation does so because it would be extremely hard to do.

However, a template can be instantiated for a class that is exportable, like

****in DLL****
__declspec(dllexport) class ExpCls
{
   ExpCls();
};
ExpCls::ExpCls()
{
   // do stuff. //
};

template<class T>class TmpCls
{
   T a;
};

***** in EXE *****
TmpCls<ExpCls> A;

Whenever the template manipulates ExpCls it will use the DLL's code.  Thus when A is constructed, the ExpCls constructor in the DLL will be called.  However, the code for calling the constructor will be in the EXE.  Any code or logic that is placed in the template will appear in the EXE (podsibly many times)  however, that code will call the DLL for manipulating the ExpCls member of the template class.
0
 
LVL 1

Author Comment

by:moshem
ID: 1172666
I did not mean that the template class itself will be exportable , but the Instance of it relative to a specific data type whould be , the extra dllexport statments are just for experimenting to find out what the problem is , so what am I doing wrong

BTW

thanks for taking the time to write a long a good answer!
0
 
LVL 22

Expert Comment

by:nietod
ID: 1172667
It would be possible for a DLL to export procedures for instances of template classes of specific types.  If an EXE needed additional types it would have generate the code instead of using the DLL.  However, I don't think that MS Vissual C++ currently does that.  I think it just does not export templates.  (Although I could be wrong and this could be tested.)

However, you can (probably) get around this using derived classes.  For example, if you have a dynamic array template class, you could export dynamic character and dynamic integer arrays as follows.  (I think)

template <class T>
class DynAry
{
  // stuff.
};

__declspec(dllexport) class IntAry : public DynAry<int>
{
};

__declspec(dllexport) class ChrAry : public DynAry<char>
{
};

0
 
LVL 1

Author Comment

by:moshem
ID: 1172668
Yes , you see that was my original question , what you just
suggested was exactly what I did in the first place ( see my
original question) the instance of the template class is'nt
exportable ( the stuff with derived class can't be right , it's
too akward , besides what's the diffrence?!) let me know what
you think
0
 
LVL 22

Expert Comment

by:nietod
ID: 1172669
I tried it.  The technique I suggested above worked, although there might have been some syntax errors.  Here is the code I just tried.

*****************************

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#define DllImp __declspec(dllimport)
#define DllExp __declspec(dllexport)

template <class T>
class DllExp TmpCls
{
  T Itm;
  TmpCls(T *Ini);
};

template <class T>
TmpCls<T>::TmpCls(T *Ini)
{
  Itm = Ini;
}

class DllExp IntCls : public TmpCls<int>
{
};

class DllExp ChrCls : public TmpCls<char>
{
};

********************************

I created a DLL using this and looked at the exports with DUMPBIN (a tool provided with vissual C++).  It exported two procedures, the constructor for IntCls and the constructor for ChrCls.

The only problem is that it generated a warning that the bass class in the declared dllexport.  The warning apparently can be ignored.  (You can get rid of the warning with a pragma dirrective.)

I'm having trouble understanding you last comment.  If this doesn't help you, ask again, a little more clearly, if possible.


0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 22

Expert Comment

by:nietod
ID: 1172670
another thing.  If this isn't what you need.  You should reject my answer so that other people can help you.  Usually other experts will put helpfull comments in locked questions, but for some reason they have not in this case.  Unlocking the question might get some more responses.  
0
 
LVL 1

Author Comment

by:moshem
ID: 1172671
The warning *IS* my problem , that is what I wanted to resolve in the first place , the code compiled but that warning puzzeled me... if you say this can be ovecome using pargma , then tell me how! anyway did you try to access that dll and create an instance of that class with no problems ?
0
 
LVL 22

Expert Comment

by:nietod
ID: 1172672
Are you sure the warning is your only problem?  I suspect that your original code did not cause the DLL to export instances of the template and I even if it did is suspect that the exe would not import instances of it.  I could be wrong, however.

Anyway, getting rid of a warning is easy.  Use
#pragma warning(disable: ####)
where #### is the warning number (the digits only) that you want to disable.  (I don't remember the number of this particular warning.)

If you don't want to dissable the warning everywhere in your code you can turn the warning back on at the end of the code that produced the warning you want to ignore.  To turn the warning back on use:
#pragma warning(default: ####)

However, the current version of Vissual C++ 5.0 doesn't handle this perfectly.  Some of the pragma warnings I have in place work perfectly all the time.  Some of them work part of the time.  That is, on some compiles they produce no error and on some they do.  I suspect the problem has to do with the use of precompiled headers and incremental compilation.  Its like the compiler is missing the pragmas when it doesn't compile a portion of the code and this causes the warnings in the portion of code that follows.
0
 
LVL 1

Author Comment

by:moshem
ID: 1172673
before we finish this discussion , can you tell me if you succeeded in creating a dll and ignoring warnings by using
the pargma , and then use it from another exe (create instance of a class or derive from it) ?
0
 
LVL 22

Expert Comment

by:nietod
ID: 1172674
I didn't test that far.  I created the dll and SAW that it had the exports listed I did NOT test that an EXE would use the exports in the DLL rather than creating the code in the EXE  But I doubt this is a problem.  

If you can't test if an EXE is using your DLL's procedures (rather than creating its own) let me know and I'll see If I can test it in a day or two.

I did not try to ignore the warnings.  Besides, the outcome of my test in this would be irrelevant to you.  You could get different results.  (From compile to compile even.)  However, this is pretty much a bug and will probably be fixed in the future.  I've been told it may be fixed in service pack 3 which was released a couple weeks ago.  I'm waiting on a copy.

0
 
LVL 1

Author Comment

by:moshem
ID: 1172675
Thanks for an excellent discussion
0
 
LVL 22

Expert Comment

by:nietod
ID: 1172676
Is it working okay for you then?  
0
 
LVL 1

Author Comment

by:moshem
ID: 1172677
I did not have time for that , but Iwill check , anyway , your help
was great , so I decieded to give you the points
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now