Questions regarding string messages in a C++ game
Hello,
How do you implement string messages for your game in C++? What I mean is for stuff like, log->Error("Something: %f", m_fSomething), or renderer->DrawText( 0, 0, "FPS: %f", m_fFPS) ??
If you use variable argument lists, you have to use vsprintf, right? Which introduces the explicit buffer size problem that the C++ way of using string streams avoids.
Now, I don't have a problem using variable argument lists, even if it is mixing C in. However, I ran across a problem. I have an exported engine class from my engine dll. The class has engine->DrawText like mentioned above, which then passes to the renderer->DrawText.
When I use the variable argument lists inside the client application, it works fine. When I use the exported DLL function, I get bad memory pointer problems. Any ideas?
Thanks.
You can turn your logger/whatever into a iostream of some kind (I've done this but it can be tricky, and possibly more work than is worth it).
I do something which most programmers would frown at.
You should probably look into boost::format. It allows for that sort of printf-style formatting, and is probably plays nicer in DLL's.
You should probably look into boost::format. It allows for that sort of printf-style formatting, and is probably plays nicer in DLL's.
I'll second the Boost.Format approach, especially since it doesn't force other people to use it -- it just means accepting a std::string instead of a char const *, so they can build that std::string any way they want.
( Boost.Format is a particularly convenient way, however :P )
( Boost.Format is a particularly convenient way, however :P )
Heheh, I found an alternate solution to what the rest of the people here are saying [smile]
Basically, my LogMessage function takes a string as it's message parameter. Now, that's all well and good, but you still have that problem of not being able to string together variables and strings. So I simply defined a few global operators, ie. string & operator + (string & source, int dest) etc, so now I just use the + operator to string together any variables I want, provided there's some string in there somewhere. Regrettably, this method doeshave some downsides, one of them being that I have to pay attention to the order I have the variables in, and sometimes switch things around. But other then that litte thing, it works like a charm!
Basically, my LogMessage function takes a string as it's message parameter. Now, that's all well and good, but you still have that problem of not being able to string together variables and strings. So I simply defined a few global operators, ie. string & operator + (string & source, int dest) etc, so now I just use the + operator to string together any variables I want, provided there's some string in there somewhere. Regrettably, this method doeshave some downsides, one of them being that I have to pay attention to the order I have the variables in, and sometimes switch things around. But other then that litte thing, it works like a charm!
Don't reinvent the wheel - at least not completely; take advantage of std::stringstreams (in header <sstream>).
Example (not tested):
Example (not tested):
#include <iostream>#include <sstream>class Message { std::stringstream buffer; public: Message() {} // just initialize the buffer template <typename T> Message(const T& first) { (*this)(first); } template <typename T> Message& operator() (const T& next) { buffer << next; } void operator() () { std::cout << buffer.str() << std::endl; } // or pass "*this" to a Logger object/module, or something... whatever // And of course you could do operator+ instead, or operator<<... // In boolean context, check if the message is non-empty. // There is probably a better way to do this. operator bool() { return buffer.str().length(); }}// Examples of useif (Message extra_info = something_wrong()) { Message("oh noes! Foo is ")(foo)(" but should be ")(bar)("!")(); extra_info();}
Thanks for all the ideas! I think I will definitely do away with variable argument lists in favor of one of these approaches. Mainly because of the DLL issue.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement