Dll & templates?

Started by
9 comments, last by AngelForce 21 years, 5 months ago
This comes from here. (you don''t have to read the thread, it''s just that I posted the same question there and it seemed to be ignored) To repeat my question: Can you use templates(STL) in a dll?? I don''t think it''s possible(I think I read some things about it) but maybe there''s a way...? Thanks for answers! AngelForce -- If you find any mistakes, you''re allowed to keep ''em! ''When I look back I am lost.''
AngelForce--"When I look back I am lost." - Daenerys Targaryen
Advertisement
because templates are instantiated on use, templated functions must be defined in the same translational unit they are used. a templated function written in one .cpp file will not be found from another .cpp file, even if both include a header with a prototype for said function.
This might be helpful: http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q168958& Exporting STL Components Inside & Outside of a Class

It is easier to use STLs in DLLs if one uses the ''pImpl'' method: (Pointer to implementation)

1-Export a pure virtual class with a limited interface (and no STLs in members. Heck, a pure virtual don''t need no members)
2-Export a function that returns a newly-created pointer to the pure virtual class
3-In the DLL, create a hidden specialization of the pure virtual class, that one can contain all the STLs and templates you like. Have the function from #2 return a pointer of this specialization.

I use that trick, and it works like a charm!

=^.^= Leaders and teachers should remember: It is best to offer others what they Need, not what they Want.
=^.^= Leaders and teachers should remember: It is best to offer others what they Need, not what they Want.
Thanks for the replies!

@Spacecat:
I would be glad to use your sollution, but I don''t really understand it =)

Could you post some code please?? (especially where[=in which file] to do what)

Thanks!

AngelForce

--
If you find any mistakes, you''re allowed to keep ''em!

''When I look back I am lost.''
AngelForce--"When I look back I am lost." - Daenerys Targaryen
Oh yeah, I was less wordy because the site kept crashing on me... hehe...

Well, first things first: Do you know how to use polymorphism in C++, and pure virtual classes? It goes something like this.

    class CPVclass{   virtual void DoSomething()=0;};class CSpecializedClass : public CPVclass{   virtual void DoSomething() {cout << "Spec class did something!";}};void main(){    CPVclass *Ptr;    Ptr = new CSpecializedClass();    Ptr->DoSomething();    delete Ptr;}    


(If you're using VC++ 6.0, make sure to active RTTI in your project settings, or this won't work)

But this is the core of polymorphism: Although you have a CPVclass pointer, any call to its functions will actually access the specialized class. And of course several classes can inherit the pure virtual class and have differing effects. Very practical to keep an array of -slightly- different objects and use them in the same manner.

Anyway, once you've understood this principle, try this in your DLL: Make it so what the DLL exports is only the pure virtual definition. NOT the specialized class you'll hide deep in the code of the DLL and never export. Then make sure you just have STLs in the specialized class.

==Program(uses DLL)==
Gets a CPV pointer from the DLL, by using CreateObject().
Only uses CPV pointers and its virtual methods.

==DLL exported methods==
CPV class; pure virtual class definition
CPV *CreateObject();

==DLL hidden stuff - NOT exported==
CPVspec class; specialization of CPV, plus STLs
CreateObject(); actually returns a new CPVspec pointer.


[edited by - Spacecat on October 23, 2002 5:01:05 PM]
=^.^= Leaders and teachers should remember: It is best to offer others what they Need, not what they Want.
Thanks for the reply, Spacecat!

I'm sorry that I didn't post earlier, but I don't have much time .
Anyway, I tried your way(by the way, I know polymorphism).

So I have the (shared) header file:

    #ifdef _DLL_EXPORT#define DLL_TEST __declspec(dllexport)#else#define DLL_TEST __declspec(dllimport)#endifclass DLL_TEST CPVclass //I took your names ;-){public:    virtual void Create(void) = 0;    virtual void DoSthElse(int a) = 0;};class CPVspec : public CPVclass{public:    void Create(void)    { /*Do Something*/}    void DoSthElse(int a)    { m_a = a;}private:    int m_a;};    


Ok, but now I'm struck =)
How to code the functions, which should return pointers?
I tried several ways, but none seems to work.

I know, I must seem quite stupid but hey, maybe I am and so I need help

Thanks anyway to spend your time!

AngelForce

__EDIT__
stupid #include/#define/...-bug
__/EDIT__

--
If you find any mistakes, you're allowed to keep 'em!

'When I look back I am lost.'

[edited by - AngelForce on October 28, 2002 4:44:08 PM]
AngelForce--"When I look back I am lost." - Daenerys Targaryen
It''s more like this:


  #ifdef _DLL_EXPORT  #define DLL_TEST __declspec(dllexport)#else  #define DLL_TEST __declspec(dllimport)#endifclassDLL_TEST CPVclass //I took your names ;-)  SpC: No prob. {public:    virtual void DoSthElse(int a) = 0;};class CPVspec : public CPVclass{public:    void DoSthElse(int a)    { m_a = a;}private:    int m_a;};    // This is the key: CreateObject cannot be in the object!// It returns a specialized Ptr, but pretends it''s a pure virtual pointer.DLL_TEST CPVclass* CreateObject(){return new CPVspec;}  


You had only one bit missing: The ''object factory'' (CreateObject) must be a standalone function, it can''t be part of the object to create. This trick is called the ''pImpl'' method. Pointer to Implementation.

Now all your main program has to use is include this DLL, use CreateObject to get a pointer, and use the functions of that pointer. You should be able to add STLs in CPVspec now, and they should work with no hassles.

=^.^= Leaders and teachers should remember: It is best to offer others what they Need, not what they Want.
=^.^= Leaders and teachers should remember: It is best to offer others what they Need, not what they Want.
Thanks very much! What would I do without such helpful people

But I also tried some things and this _seems_ to work too(havn't tested it much, but it compiles and runs fine) :


      //HEADER(dll & prog)-------------------------#include <string>class FFoo{public:	void writestr(std::string str){m_str = str;}private:	std::string m_str;};DLL_WIZ_API class Foo{public:	void Dosth(void);	void write(char* a)	{		ff.writestr(a);	}private:	FFoo ff;};//MAIN.CPP (prog)Foo f;f.write("!!test!!");   


What do you think? I dunno if this works always(for example, I havn't tried it the other way[returning string]), but if we could just create a class 'templates' (storing all templated) with functions to manipulate them...maybe it even works just like


  class FFoo{public:	std::string* getstring(void) {return &m_str;}private:	std::string m_str;};      

but I havn't found time to test it yet.

Anyway, what you think??
(This seems to become a dialog between us )

AngelForce

--
If you find any mistakes, you're allowed to keep 'em!

'When I look back I am lost.'

[edited by - AngelForce on October 29, 2002 10:36:50 AM]

[edited by - AngelForce on October 29, 2002 10:37:33 AM]
AngelForce--"When I look back I am lost." - Daenerys Targaryen
Oh yeah, that second trick you used with Foo and FFoo is another way to hide the STL from the DLLexport problem. That one is supposed to work too, yeah.

But your last idea ''should not''. (I haven''t tested) Here''s the general idea of why: According to MSDN, in order to export a template member in an exported DLL class, "there''s a lot of hassle involved" (short version of their three-page article)

Solution: Do NOT try to export a STL member or output parameter or input parameter in a DLL exported class. Since your FFoo class just had a pointer to another class, and the pImpl method fully hides another class, those methods avoided the problem.

However do notice them: In neither the pImpl or in your ''pointer to Foo as a member'' methods, you used a STL anywhere as input or output parameter. Now I''m not 100% sure but I think things will start screwing up the second STLs are passed as parameters from the exported member functions. Test to be sure, read MSDN for the really complicated workarounds. (Me I use pImpl, period)

You got ways to work now, I think this can be considered ''case closed'', hm?
=^.^= Leaders and teachers should remember: It is best to offer others what they Need, not what they Want.

This topic is closed to new replies.

Advertisement