• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
harshman_chris

Dealing with "needs to have dll-interface to be used by clients of class"

13 posts in this topic

I like warning free code, especially for a dll, these warnings are the only left right now I have to deal with. I am not sure how to deal with them however. If someone could point me in the right direction that would be great.

 

std::basic_string<_Elem,_Traits,_Ax>
std::map<_Kty,_Ty>
std::vector<_Ty>
std::list<_Ty>'
std::_List_iterator<_Mylist>

 

Update:

 

So to compound this, I get this error when setting up my .exe project:

 

 

Error 49 error C2491: 'ParticlesEngine::Singleton<T>::instance' : definition of dllimport static data member not allowed

 

The Code:

 

#ifndef _SINGLETON_H
#define _SINGLETON_H

#define NULL 0


#ifdef PARTICLESENGINE_DLL 
#define PARTICLESENGINE_API __declspec( dllexport )
#else
#define PARTICLESENGINE_API __declspec( dllimport )
#endif

namespace ParticlesEngine
{

	template <typename T>
	class PARTICLESENGINE_API Singleton
	{
	public:
		Singleton<T>(void)
		{    
		}
 
		static inline T* getInstance(void) 
		{ 
			if(instance == NULL) 
			{
				instance = new T();
			}
			return instance;
		} 

		static inline bool exists( void ) { return instance != 0; }
   
		virtual ~Singleton( void ) { instance = 0; }

	protected:
		static T* instance;
	};

	template <typename T>
	T* Singleton<T>::instance = 0;

}

#endif

 

 

 
Edited by harshman_chris
0

Share this post


Link to post
Share on other sites

Warning C4251. You have a DLL interface that depends on code that is compiled externally, is statically linked into the DLL & EXE, and as a result you may have a version mis-match between the data structure used in the DLL, vs the 'same' (but possibly not) data structure used in the exe.

 

In a nutshell, if your DLL links to the release CRT, and then returns a std::string. That string will be allocated in the DLL, and may end up being freed/reallocated in the EXE. Even worse, the data sizes of the STL containers may change size (i.e. iterator debugging info), which can cause all manner of buffer overruns and other niceties.

 

To avoid this warning, you have two choices:

 

a) Don't use STL,

b) Don't use STL.

 

There is a third option, which is to simply ignore the warning. The warning is only a problem when trying to link a debug build DLL with a release build app (or visa-versa). If both EXE & DSO are linking to the same CRT, then there is no problem.

As for you other problem, stop putting the class implementations as non-inlined parts of a header file. This won't work with DLLs. The second you attempt to link to the DSO, the static variable is declared as a new global variable in the executable, and it's declared as being "dllimport", which is WRONG. It needs to be declared once in your DLL as "dllexport". Source files are there for a reason! Use them more! :p

1

Share this post


Link to post
Share on other sites

Alright I kinda though that, I will go edit my headers to correct that issue.

 

About stl, I can switch to char instead of string for most of it, it will take a bunch of work, but how can I replace vector and map and list which I use alot without having to write my own.

 

Thanks

0

Share this post


Link to post
Share on other sites

[Actually there is another way to avoid the STL problem.....  Don't expose in in the DSO interface]

 

[code]class Foo { public:   EXPORT Foo();   EXPORT Foo(const Foo&);   EXPORT ~Foo();     EXPORT const char* name() const;   EXPORT void setName(const char* n); private:   std::string m_name; };[/code]

 

And just to keep the pedants at bay, you can finalise the class if you really want to avoid the problem of 'Foo' being of an unknown size (although disabling SECURE_CSL and building the DSO in release normally avoids all but the most extreme edge cases).

 

[code]class Foo {   Foo(const Foo&); public:   EXPORT static Foo* create();   EXPORT ~Foo();     EXPORT const char* name() const;   EXPORT void setName(const char* n); private:   std::string m_name; };[/code]

1

Share this post


Link to post
Share on other sites
Alright I kinda though that, I will go edit my headers to correct that issue.

 

About stl, I can switch to char instead of string for most of it, it will take a bunch of work, but how can I replace vector and map and list which I use alot without having to write my own.

 

Thanks

 

 

Stop exporting the entire f***ing class! Exporting the entire class is really bad practice. It will attempt to export ALL of your member variables, private functions, inline functions, etc. Just export the public functions you need, and be done with it (but remember to always export the ctor, copy ctor, dtor; and also make sure that your ctor is virtual if you intend to use it as a base class. This isn't 'good practice', it's required).

 

You can pass simpler forms of container across the boundary provided their layout and size remain constant. Pass this class by value across the DLL boundary, AND DO NOT EXPORT IT!!  (It's inline for a reason!)

 

[code]template< typename T >
class ConstVector
{
public:

    inline ConstVector( const std::vector<T>& data )
        : m_begin(0), m_end(0)
    {
        if(data.size())
        {
            m_begin = &data[0];
            m_end = m_begin + data.size();
        }
    }

    inline ConstVector( const ConstVector<T>& data )
        : m_begin(0), m_end(0)
    {
    }

    inline ~ConstVector()
    {
    }

    inline size_t size() const
    {
        return m_end - m_begin;
    }

    inline const T* begin() const
    {
        return m_begin;
    }

    inline const T* end() const
    {
        return m_end;
    }

    inline operator std::vector<T> () const
    {
        return m_begin ? std::vector<T>(m_begin, m_end) : std::vector<T>();
    }

private:
    const T* m_begin;
    const T* m_end;
};[/code]

 

(I've not actually tested that code, but it should be about right..... )

1

Share this post


Link to post
Share on other sites

[quote name='RobTheBloke' timestamp='1358442286' post='5022571']
Stop exporting the entire f***ing class! Exporting the entire class is really bad practice. It will attempt to export ALL of your member variables, private functions, inline functions, etc. Just export the public functions you need, and be done with it
[/quote]

 

Specify your interface to the library.  This is true any time you cross a boundary (such as a dll or even a networking protocol).

 

[quote name='RobTheBloke' timestamp='1358441477' post='5022564']
a) Don't use STL,
b) Don't use STL.
[/quote]

Icky.

 

Use the standard library.  Use it and embrace it.  The library is incredibly useful.

 

DLLs have a very clear type of interface.  That interface passes buffers of data, not c++ objects.  

 

It isn't that much different than any other boundary, such as a network boundary or file system boundary; you don't just dump the entire class but instead serialize the data into a boundary-crossing interface.

2

Share this post


Link to post
Share on other sites

a) Don't use STL,
b) Don't use STL.

 

Icky.

 

Use the standard library.  Use it and embrace it.  The library is incredibly useful.


15 years ago I had that opinion, but after a far too many years maintaining the plug-in architectures for a number of 3D apps, I've developed a lot of contempt for the design of STL allocators & containers (the algorithms are fine, if a little inefficient in places). Yes you can approach everything with a serialise/deserialise mindset, but it just leads to performance hot spots in my experience (or more accurately, it just makes everything a little bit warm all over). If at some point down the line you need to resolve the performance issues, it becomes a real PITA. For any DSO heavy application, it's going to be far easier to simply restrict yoruself to using your own containers (which are of a known size & implementation that you can easily pass across the boundary directly). STL just gets in the way of that imho. I've yet to see a single DLL whose quality is improved by the presence of STL.....  Most of the time, it simply encourages junior developers to make silly mistakes in the API (for example, forgetting that returning const reference to a std::vector is bad news).  My 2 cents.

2

Share this post


Link to post
Share on other sites

Alright there is a lot of information above I am working on understanding, thank you all for your help so far.

 

So to not export the entire class I need to add "EXPORT" in front of everything I want to export in the header files. However I shouldn't add EXPORT to functions that are Inline? In addition I should change all my functions that take std::string as a parameter to char, and then keep the std::string's internal or get rid of them all together.

 

 

To the other issue with static data members, I moved the Singleton<T>::instance to the c++ file, now I get Linker errors for each class which is a singleton, which then causes more issues.

 

I am not sure how to solve this:

 

My Singleton c++ just to make sure I did make any errors.

 

#include "Singleton.h"

using namespace ParticlesEngine;

template <typename T>
T* Singleton<T>::instance = 0;
Edited by harshman_chris
0

Share this post


Link to post
Share on other sites

You need to export EACH specialisation to the DLL. You cannot export a template to a DLL.

 

template class DLL_EXPORT Singleton<FooType1>;

1

Share this post


Link to post
Share on other sites
You need to export EACH specialisation to the DLL. You cannot export a template to a DLL.

 

template class DLL_EXPORT Singleton<FooType1>;

 

 

Something like this, but this doesn't work.

#include "Singleton.h"

#include "GameInfo.h"
#include "Logger.h"
#include "SoundManager.h"
#include "SceneManager.h"
#include "ResourceManager.h"

using namespace ParticlesEngine;

template class DLL_EXPORT GameInfo* Singleton<GameInfo>::instance = 0;
template class DLL_EXPORT Logger* Singleton<Logger>::instance = 0;
template class DLL_EXPORT SoundManager* Singleton<SoundManager>::instance = 0;
template class DLL_EXPORT SceneManager* Singleton<SceneManager>::instance = 0;
template class DLL_EXPORT ResourceManager* Singleton<ResourceManager>::instance = 0;
0

Share this post


Link to post
Share on other sites

Originally you were exporting the entire singleton class no? That kinda implies you are trying to do this:

 

[code]// Implementation MUST be in the cpp file (otherwise it gets redefined in the header file in multiple compilation units) template<typename T> T* Singleton<T>::instance = 0;
// and now we export the class specialisations.
template class DLL_EXPORT Singleton<GameInfo>;
template class DLL_EXPORT Singleton<Logger>;
template class DLL_EXPORT Singleton<SoundManager>;
template class DLL_EXPORT Singleton<SceneManager>;
template class DLL_EXPORT Singleton<ResourceManager>;
[/code]

 

If you just want to export the variable only, leaving the rest inline, then :

 

[code]
template DLL_EXPORT GameInfo* Singleton<GameInfo>::instance = 0;
template DLL_EXPORT Logger* Singleton<Logger>::instance = 0;
template DLL_EXPORT SoundManager* Singleton<SoundManager>::instance = 0;
template DLL_EXPORT SceneManager* Singleton<SceneManager>::instance = 0;
template DLL_EXPORT ResourceManager* Singleton<ResourceManager>::instance = 0;
[/code]

1

Share this post


Link to post
Share on other sites

A couple of things, I need to replace DLL_EXPORT with PARTICLESENGINE_API from this:

#ifdef PARTICLESENGINE_DLL 
#define PARTICLESENGINE_API __declspec( dllexport )
#else
#define PARTICLESENGINE_API __declspec( dllimport )
#endif

 

 

Also there is this error now:

 

 

Error 33 error C2143: syntax error : missing ';' before '=' c:\users\100312531\desktop\project-seventeen\particleengineproject\particlesengine\singleton.cpp 12 1 ParticlesEngine

 

that happens on each of those variable declaration lines

 
0

Share this post


Link to post
Share on other sites

Ahh yup, you might have wanted this instead. My bad!

 

[code]  // Implementation MUST be in the cpp file (otherwise it gets redefined in the header file in multiple compilation units) template<typename T> T* Singleton<T>::instance = 0; template PARTICLESENGINE_API GameInfo* Singleton<GameInfo>::instance; template PARTICLESENGINE_API Logger* Singleton<Logger>::instance; template PARTICLESENGINE_API SoundManager* Singleton<SoundManager>::instance; template PARTICLESENGINE_API SceneManager* Singleton<SceneManager>::instance; template PARTICLESENGINE_API ResourceManager* Singleton<ResourceManager>::instance;[/code]

0

Share this post


Link to post
Share on other sites

No Worries, thank you for all your help.

 

There is one more issue left which is similar but different enough to warrant another post, rather than continue this one.

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0