C Board  

Go Back   C Board > Platform Specific Boards > Windows Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 12-13-2008, 07:28 AM   #1
Registered User
 
starcatcher's Avatar
 
Join Date: Feb 2008
Location: Australia
Posts: 41
Question How to solve warnings that appear when building my DLL...

Hi,

As it may be apparent from my previous thread, I am trying to get 'making my own DLLs' sorted out. I ran into a problem when I was building my DLL yesterday (which just contains a few classes). Some of my classes have members that are of the type 'std::string', and while the DLL builds without errors, numerous warnings appear. These are all of the following form:
Code:
c:\Program Files\Webots\include\controller\mycpp\webots\Device.hpp(34) :
warning C4251: 'webots::Device::name' : class 'std::basic_string<_Elem,_Traits,_Ax>' needs
to have dll-interface to be used by clients of class 'webots::Device'
I understand why these warnings are occurring, as a client program is not guaranteed to have included <string>, which defines the basic_string class, and so is not guaranteed to be able to use the 'name' member of the Device class for example, in the case above. I do not know however, how to get rid of these warnings, without simply ignoring or disabling them. There has got to be a way around this...

And just for the record, I use MSVC++ 2003.

Thanks,

Philipp
__________________
I program solely as a hobby so this is definitely not homework.
Best thing that's been said to me:
Quote:
I was so pleasantly surprised to see another post in this thread, and yours was brilliant; a fitting end to a subject (matrix manipulations of all kinds) that is quite intriguing.
Read this thread to find out why...
Cannibalism
starcatcher is offline   Reply With Quote
Old 12-13-2008, 08:12 AM   #2
Registered User
 
Codeplug's Avatar
 
Join Date: Mar 2003
Posts: 3,844
You shouldn't pass CRT or STL objects across module (dll/exe) boundaries. When you export a class, you implicitly export all members and base classes.

http://msdn.microsoft.com/en-us/library/ms235460.aspx
http://msdn.microsoft.com/en-us/library/twa2aw10.aspx

Any easy solution is to use the pimpl idiom to "hide" implementation details.
http://www.gotw.ca/gotw/024.htm

gg
Codeplug is offline   Reply With Quote
Old 12-13-2008, 12:08 PM   #3
Super Moderator
 
Bubba's Avatar
 
Join Date: Aug 2001
Posts: 7,472
Actually you can pass STL objects it's just that to do so requires a specific export statement. I believe the docs you referred to explain this.
__________________
If you aim at everything you will hit something but you won't know what it is.
Bubba is offline   Reply With Quote
Old 12-13-2008, 12:59 PM   #4
Registered User
 
Codeplug's Avatar
 
Join Date: Mar 2003
Posts: 3,844
Yes, but it's not safe unless you use the exact same STL implementation with the exact same build options. It's just too easy for things to go wrong.

gg
Codeplug is offline   Reply With Quote
Old 12-13-2008, 01:53 PM   #5
Algorithm Dissector
 
iMalc's Avatar
 
Join Date: Dec 2005
Location: New Zealand
Posts: 2,476
Quote:
Originally Posted by Codeplug View Post
Yes, but it's not safe unless you use the exact same STL implementation with the exact same build options. It's just too easy for things to go wrong.
I agree.
There's a reason Microsoft never do it.
__________________
My homepage
Advice: Take only as directed - If symptoms persist, please see your debugger
iMalc is offline   Reply With Quote
Old 12-14-2008, 12:15 AM   #6
Registered User
 
starcatcher's Avatar
 
Join Date: Feb 2008
Location: Australia
Posts: 41
Question How to do that?

I read through all the links you gave me, but I still don't understand how to use the pimpl_ idiom in a way that would help me with my problem. Could you help me by describing how I could use it for example with this class, which appears in one of my headers:
Code:
#include <webots\MyCpp.hpp>
#include <string>

namespace webots {
  class DECLSPEC Device {
    public:
      virtual ~Device() {}
      const std::string getName() const {
        return name;
      }
      bool isValid(void) const {
        return (tag!=0);
      }
    protected:
      Device(const std::string &name);
      WbDeviceTag getTag() const {
        return tag;
      }
    private:
      WbDeviceTag tag;
      std::string name;
  };
}
The definition of DECLSPEC is as follows, which is taken from MyCpp.hpp:
Code:
// Define DLL macros
#ifdef MYCPPCONTROLLER_EXPORTS
#define DECLSPEC	__declspec(dllexport)
#else
#define DECLSPEC	__declspec(dllimport)
#endif
Or is there another way that I could overcome the warnings?

Thanks,

Philipp
__________________
I program solely as a hobby so this is definitely not homework.
Best thing that's been said to me:
Quote:
I was so pleasantly surprised to see another post in this thread, and yours was brilliant; a fitting end to a subject (matrix manipulations of all kinds) that is quite intriguing.
Read this thread to find out why...
Cannibalism

Last edited by starcatcher; 12-14-2008 at 08:28 AM. Reason: Added question at end
starcatcher is offline   Reply With Quote
Old 12-14-2008, 11:47 AM   #7
Registered User
 
Codeplug's Avatar
 
Join Date: Mar 2003
Posts: 3,844
Ideally, your DLL interface would only expose / transfer POD types - or other exported types. Since Device is using std:string, it's implicitly exported (which causes the warning). Here is how you could either change to POD's only, or use PIMPL idiom to hide the implementation details within the DLL - separate from the DLL interface.
Code:
class foo
{
    std::string m_name;

public:
    foo(const std::string &name) : m_name(name) {}
    ~foo() {}

    std::string GetName() const {return m_name;}
};//foo

class foo_POD
{
    char *m_name;

public:
    foo_POD(const char * name) : m_name(strdup(name)) {}
    ~foo_POD() {free(m_name);}

    const char* GetName() const {return m_name;}
};//foo_POD

class foo_pimpl
{
    struct foo_imp; // forward declaration
    foo_imp *m_pimpl;

public:
    foo_pimpl(const char *name);
    ~foo_pimpl();

    const char* GetName() const;
};//foo_pimpl

// ----------------- foo_pimpl.cpp --------------------

struct foo_pimpl::foo_imp
{
    std::string m_name;
};//foo_imp

foo_pimpl::foo_pimpl(const char *name)
{
    m_pimpl = new foo_imp;
    m_pimpl->m_name = name;
}//constructor

foo_pimpl::~foo_pimpl()
{
    delete m_pimpl;
}//destructor

const char* foo_pimpl::GetName() const
{
    return m_pimpl->m_name.c_str();
}//GetName
If you are the only customer of your DLL - and can build all modules that use it when ever it changes (with identical project settings) - then you could keep what you have and explicitly export std::string to get rid of the warning. Another link to read: http://support.microsoft.com/default...B;EN-US;168958

gg

Last edited by Codeplug; 12-14-2008 at 11:50 AM.
Codeplug is offline   Reply With Quote
Reply

Tags
class, dll, export, member, warning

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
non-MFC DLL with MFC app question. Kempelen Windows Programming 10 08-20-2008 07:11 AM
building a DLL sass C++ Programming 1 03-02-2006 05:25 AM
dll communicating between each other cloudy C++ Programming 5 06-17-2005 02:20 AM
DLL and std::string woes! Magos C++ Programming 7 09-08-2004 12:34 PM
.lib vs .h vs .dll Shadow12345 C++ Programming 13 01-01-2003 05:29 AM


All times are GMT -6. The time now is 02:22 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22