I need an interface to write short messages to a log file, the messages often contains multiple parts such as an identifier together with a value.
In order to do this I've created a class that handles a lot of minor stuff such as creating filenames with timestamps and so on, although I don't want to use a variable argument list (int nargs, ...), so I thought my best option was to pass a std::stringstream to the write function instead.
I want to be able to write these calls as one-liners and not having to create a std::stringstream every time I need to do this, therefore I created a static member function to return a stringstream object I could use with my write function, although for some reason it doesn't work.
MyClass.h
class MyClass {
public:
static std::stringstream& stream();
void write(std::ostream& datastream);
private:
static std::stringstream* _stringstream;
};
MyClass.cpp
std::stringstream* MyClass::_stringstream = new std::stringstream();
std::stringstream& MyClass::stream() {
MyClass::_stringstream->str(std::string());
return *MyClass::_stringstream;
}
void MyClass::write(std::string data) {
this->_fhandle << data << std::endl;
}
void MyClass::write(std::ostream& datastream) {
std::string data = dynamic_cast<std::ostringstream&>(datastream).str();
this->write(data);
}
main.cpp
MyClass* info = new MyClass();
info->write("Hello, world");
info->write(MyClass::stream() << "Lorem" << ", " << "ipsum");
info->write(MyClass::stream() << "dolor sit" << " amet");
The code compiles, but when executing the application I get a std::bad_cast exception...
That's because you are creating an std::stringstream, which
doesn't derive from an std::ostringstream. Just create an
std::ostringstream, and the bad_cast should disappear.
Having said that, reusing the std::ostringstream many times
like this is generally not a good idea; the iostream classes are
full of state, which will not be reset between each use. It's
better to create new instance each time. (The classical
solution for this sort of thing is to create a copiable wrapper
class, which forwards to an std::ostream. An instance of this
is returned by info->write(), so you can write info->write() << "Hello, world" ....)
Related
EDIT:
I have modified the example API so it better reflects the real API I am dealing with. The way the API get's the message argument passed to it is by user input so the message argument cannot be used to pass additional data.
I am dealing with a very frustrating API that uses callback routines that don't take "void* userarg" pointers.
Assuming the function that uses the callback routine as defined by the API expects a string argument (that will be assigned by user input), is there ANY possible way to get more data into my callback routine without using global variables?
Here is a simplified example of what the API might look like:
#include <iostream>
using namespace std;
////////////////////////////////////////////////////////////////////////////////
// ASSUME EVERYTHING IN THIS SECTION IS PART OF AN API AND IS NOT MY OWN CODE...
// I DO NOT HAVE THE SOURCE AND IT CANNOT BE MODIFIED
typedef void (*CALLBACK)(string message);
void call_callback(CALLBACK cb) {
// Gets a message from user input
string message = "hello"; // pretend this is user input
cb(message);
}
////////////////////////////////////////////////////////////////////////////////
int data = 42;
void callback_function(string message) {
// I want to access "data" here WITHOUT it being global
cout << message << ' ' << data << endl;
}
int main(int argc, char** argv) {
call_callback(&callback_function);
}
Typically an API that uses callbacks would also pass a "void* userarg" argument into the callback routine so you could pass additional data of any type, but that is not the case here.
This API is used extensively throughout our whole codebase and it is 100% necessary to pass a lot more data in every case where it is used. The current way we get more data in *prepare to cringe* is by storing practically all of our data in singletons so nearly everything is global and can be accessed from literally anywhere in the program.
This whole concept seems EVIL to me, but without a better API I can't figure out any better way to get the data into the callback. I have already contacted the vendor and asked that they fix their API to make it accept a "void* userarg" argument, but it doesn't look like it will be fixed anytime in the near future...
All I am hoping for is ANY better way of doing things than we are now.
If it is really an std::string which is an argument to the callback (and not something else) and you really have access to the argument (as in your sample code which invokes call_callback with supplied string) you can put an entity-serialized pointer to your allocated object into std::string (which is allowed to have arbitrary data in it) and invoke call_callback with it.
One challenge here would be the fact that you'd than have to manually manage this pointer.
My most straightforward idea would be to provide unique strings in place of the void* you would normally expect. You'd then have one map singleton that maps the strings to your callbacks.
So something like this:
class Dispatcher
{
public:
// TODO: Thread safety etc.
std::string makeCallback(std::function<void()> callback)
{
std::string uid = std::to_string(_index);
_callbacks[uid] = std::move(callback);
_index++;
return uid;
}
void runCallback(std::string uid)
{
_callbacks[uid]();
}
private:
size_t _index = 0;
std::map<std::string, std::function<void()>> _callbacks;
};
void leaveAPI(std::string uid)
{
getSingleton<Dispatcher>()->runCallback(uid);
}
void enterAPI(std::function<void()> userCallback)
{
std::string uid = getSingleton<Dispatcher>()->makeCallback(userCallback);
call_callback(leaveAPI, uid);
}
Demo
You just count up a number every time you call the API and use its string version as the callback parameter. The class also maps each of those strings to the callback you wanted called. You could remove the map entries or do any number of performance optimizations, but this is the gist of it.
(This would work just as well with const char* if you figure out the ownership/lifetime questions that it opens.)
You should really petition the writers of the API to use std::function instead of raw pointers to functions.
Then you can easily use e.g. std::bind or lambda expressions to be able to call functions taking more arguments than the callback takes.
For example:
// The callback is a function taking one string argument, and return nothing
using CALLBACK = std::function<void(std::string)>;
// Do some processing and then call the callback function
void call_callback(CALLBACK cb, std::string message)
{
// ...
cb(message);
}
// Our callback takes a string *and* an integer argument
void callback_function(std::string message, int data)
{
std::cout << message << ' ' << data << '\n';
}
int main()
{
int local_data = 42;
// Using std::bind...
using namespace std::placeholders; // for _1, _2, _3...
call_callback(std::bind(&callback_function, _1, local_data), "Foobar");
// Using lambdas...
call_callback([local_data](std::string message)
{
callback_function(message, local_data);
}, "Foobar");
}
Using std::function also makes it easy to use member functions as callbacks as well, not only non-member functions (or static member functions).
However, if you can't modify the API, or the creator of it won't change it and it have to use C-style plain pointers to non-member functions, you can still solve it with lambdas, but you can't have any captures for the lambda:
call_callback([/*empty!*/](std::string message)
{
// Call the function as defined in the previous snippet
callback_function(message, 42); // Pass the value directly
}, "Foobar");
I found this question answered for Python, Java, Linux script, but not C++:
I'd like to write all outputs of my C++ program to both the terminal and an output file. Using something like this:
int main ()
{
freopen ("myfile.txt","w",stdout);
cout<< "Let's try this";
fclose (stdout);
return 0;
}
outputs it to only the output file named "myfile.txt", and prevents it from showing on the terminal. How can I make it output to both simultaneously? I use visual studio 2010 express (if that would make any difference).
Thanks in advance!
Possible solution: use a static stream cout-like object to write both to cout and a file.
Rough example:
struct LogStream
{
template<typename T> LogStream& operator<<(const T& mValue)
{
std::cout << mValue;
someLogStream << mValue;
}
};
inline LogStream& lo() { static LogStream l; return l; }
int main()
{
lo() << "hello!";
return 0;
}
You will probably need to explicitly handle stream manipulators, though.
Here is my library implementation.
There is no built in way to do this in one step. You have to write the data to a file and then write the data out on screen in two steps.
You can write a function that takes in the data and the filename and does this for you, to save you time, some sort of logging function.
I have a method to do this, and it is based on a subscriber model.
In this model all your logging goes to a "logging" manager and you then have "subscribers" that decide what to do with the messages. Messages have topics (for me a number) and loggers subscribe to one or more topic.
For your purpose, you create 2 subscribers, one that outputs to the file and one that outputs to the console.
In the logic of your code you simply output the message, and at this level not need to know what is going to be done with it. In my model though you can check first if there are any "listeners" as this is considered cheaper than constructing and outputting messages that will only end up in /dev/null (well you know what I mean).
One way to do this would be to write a small wrapper to do this, for example:
class DoubleOutput
{
public:
// Open the file in the constructor or any other method
DoubleOutput(const std::string &filename);
// ...
// Write to both the file and the stream here
template <typename T>
friend DoubleOutput & operator<<(const T& file);
// ...
private:
FILE *file;
}
To have a class instead of a function makes you use the RAII idiom (https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization)
To use it:
DoubleOutput mystream("myfile");
mystream << "Hello World";
I'm working on a project that delivers statistics to the user. I created a class called Dog,
And it has several functions. Speak, woof, run, fetch, etc.
I want to have a function that spits out how many times each function has been called. I'm also interested in the constructor calls and destructor calls as well.
I have a header file which defines all the functions, then a separate .cc file that implements them. My question is, is there a way to keep track of how many times each function is called?
I have a function called print that will fetch the "statistics" and then output them to standard output. I was considering using static integers as part of the class itself, declaring several integers to keep track of those things. I know the compiler will create a copy of the integer and initialize it to a minimum value, and then I'll increment the integers in the .cc functions.
I also thought about having static integers as a global variable in the .cc. Which way is easier? Or is there a better way to do this?
Any help is greatly appreciated!
Using static member variables is the way to go. However, the compiler will not "create a copy of the integer and initialize it to a minimum value"; you'll have to provide a definition for each one in the .cc file and initialize it to 0 there. (Things are a bit different if you're using C++11, but the basic idea is the same.)
There's no reason to use static global variables instead of static members.
foo.h:
class Foo {
static int countCtor_;
static int countDtor_;
static int countprint_:
Foo();
~Foo();
static void print();
};
foo.cc:
#include <iostream>
#include "foo.h"
int Foo::countCtor_ = 0;
int Foo::countDtor_ = 0;
int Foo::countprint_ = 0;
Foo::Foo() {
++countCtor_;
// Something here
}
Foo::~Foo() {
++countDtor_;
// Something here
}
void Foo::print() {
++countprint_;
std::cout << "Ctor: " << countCtor_ << "\n"
<< "Dtor: " << countDtor_ << "\n"
<< "print: " << countprint_ << "\n";
}
But if you've got a lot of functions, the repetition involved is a bit annoying—it's very easy to accidentally do ++countBar_ when you meant ++countBaz_ (especially if you copy and paste the boilerplate), so you may want something a bit fancier, such as a static map and a macro that increments counts[__FUNC__], so you can just use the exact same line in each function. Like this:
foo.h:
#include <map>
class Foo {
static std::map<const char*, int> counts_;
Foo();
~Foo();
void print();
};
foo.cc:
#include <iostream>
#include "foo.h"
std::map<const char *, int> Foo::counts_;
#define INC_COUNT_() do { ++counts_[__FUNC__]; } while (0)
Foo::Foo() {
INC_COUNT_();
// Something here
}
Foo::~Foo() {
INC_COUNT_();
// Something here
}
void Foo::print() {
INC_COUNT_();
for (std::map<const char *, int>::const_iterator it = counts_.begin();
it != counts_.end(); ++it) {
std::cout << it->first << ": " << it->second << "\n";
}
}
In the example code above, __FUNC__ is a placeholder. Unfortunately, there is no standard-compliant value you can use in its place. Most compilers have some subset of __func__, __FUNC__, __FUNCTION__, __FUNCSIG__, and __PRETTY_FUNCTION__. However, none of those are standard in C++03. C++11 does standardize __func__, but only as an "implementation-defined string", which isn't guaranteed to be useful, or even unique. On top of that, the values will be different on different compilers. Also, some of them may be macros rather than identifiers, to make things more fun.
If you want truly portable code, in C++11, you can use something like string(__func__) + ":" + STRINGIZE(__LINE__)—this will be somewhat ugly, but at least each function will have a unique name. And in C++03, there is no equivalent. If you just need "portable enough", consult the documentation for every compiler you use, or rely on something like autoconf.
Is there any reason you can't use standard profiling tools that will count these calls for you? Something like gprof?
Otherwise static integers would be the way to go.
Assuming you want these statistics tracked all the time in your program, you could use an unordered_map of your function names:
std::unordered_map<const char *, unsigned> stats;
void foo () {
// use __FUNCDNAME__ for MSVC
++stats[__PRETTY_FUNCTION__];
//...
}
The use of compiler specific function name specifiers is purposefully there to get the decorated function names. This is so that overloaded function names get counted as separate functions.
This technique allows you to add new functions easily without thinking about anything else, but there is a small additional cost if there are hash collisions (which can be remedied somewhat by sizing the stats map to be larger). There is no hash computed on the string, since the key is a pointer type, it just uses the pointer value itself as the hash.
If this is just one-off code for profiling, then you should first try to use the code profiling tools available on your platform.
You can put static locals inside the methods themselves, that seems cleaner since these variables aren't logically connected to the class so there's no reason to make them members.
Additionaly, you could have a macro to simplify the work. I normally don't recommend using macros, but this seems like an appropriate use:
#define DEFINE_COUNTER \
static int noCalls = 0; \
noCalls++;
void foo()
{
DEFINE_COUNTER
}
Use a library that implements the Observer Pattern or Method Call Interception. You can choose one from this list, or use something like Vitamin.
I have a lot (perhaps hundreds) of different c++ files. Each one contains 10 functions, all of them taking in an int and a double and returning an int.
So the pointer to one of these functions in one of these files would look like this:
int (*foo)(int, double);
And then I have a class, which contains 10 of these function pointers.
Is it possible to have the constructor of this class take in a file name of one of these c++ files, put that file's functions into its pointers, and be able to use the functions later?
Preferably it would work so that even if two functions from different files had the same name it would still work (the idea is that multiple programmers could submit different files into the list, and they might use the same names for their 10 functions), but if that's not possible I could figure out something to avoid that.
From what I've searched, I can't seem to find anything that lets you differentiate between files when choosing functions, and even if I were to concatenate the functions into one file, there's still the problem of trying to designate which 10 functions to pick (as they all have the same arguments).
Is there any way to do this? Is there any better solution that I'm just not thinking of?
Is there any way to do this? Is there any better solution that I'm
just not thinking of?
You could just use different namespaces for them I think ? I mean each group of 10 functions in their own namespace; that way they won't conflict any more.
Other than that, you could try some dlsym + dlopen weirdness (or their win32 counterparts). It's not something I would do though.
I believe you are describing a dynamic linking library (aka shared object in Linux-land).
To achieve what you ask literally, you can turn each C++ file into a dynamic library and in the library constructor register the set of functions in some global map using FILE string as a key or declare them static, and make sure each file has some static variable whose initializer triggers functions' registration in the same global map.
To implement the same using plugin approach you can do it the way similar to what I have done it here (just download plugin.tgz, article is not yet ready). Contents:
app.cc - application, loads all plugins' libraries
module.cc - a plugin class implementing a business interface
module_ifc.h and a "loadable" interface bootstrap_ifc.h
client.cc - a plugin implementing bootstrap_ifc.h and using
method from module.cc resolved at runtime
Each of your C++ files having the same set of function would have a class implementing abstract business interface (useful part, all your functions) and bootstrap interface (unified initialization part, will be used by plugin loader). Each such class would be put into a separate shared library that declares class instance constructor and destructor methods.
A simple class to work with shared libraries on Linux:
#include <dlfcn.h>
class library {
void* _handle;
public:
library(char const* path);
~library();
template <typename F> F func(char const* name);
};
library::library(char const* path) {
_handle = dlopen(path, RTLD_NOW);
if (!_handle) throw std::runtime_error(dlerror());
std::clog << "opened library " << path << ", handle=" << std::hex << _handle << std::dec << "\n";
}
library::~library() {
if (_handle) dlclose(_handle);
std::clog << "closed library, handle=" << std::hex << _handle << std::dec << "\n";
}
template <typename F> F library::func(char const* name) {
dlerror();
F func = reinterpret_cast<F>(dlsym(_handle, name));
const char *dlsym_error = dlerror();
if (dlsym_error) throw std::runtime_error(dlsym_error);
std::clog << "loaded symbol " << name << ", ptr=" << std::hex << ((void*)func) << std::dec << "\n";
return func;
}
I am in progress of refactoring a C++ application of mine. Before I used a macro like
LOG("something interesting") // 1
LOG("something ended") // 2
LOG("foo: " << bar) // 3
My idea now was to write a Log class like so:
Log(std::string _init_message):
init_message(_init_message)
{ PrintLogLine(init_message + " ...");}
~Log()
{ PrintLogLine(init_message + " done.");}
to get "automatic" logging of specific actions (i.e. when they start, stop + additionally timings etc.) when I use it like
void ActionXYZ() {
Log log("xyz");
// do stuff
}
Where I am struggling is in defining a way to make it work for case 3). In Java I could use a method which takes one String argument since the compiler takes care of automatically string building. What possibilities do I have in C++?
Can I make it work so that I can use it like either one option?
// in "do stuff"
log("foo:" + bar); // OR
log << "foo:" << bar;
As I've mentioned in the comments, you could use Boost.Format. It also helps with the problem of int-to-string conversions, etc. It might get a bit verbose, though — to avoid calling .str() to call std::string constructor, you could make one that accepts boost::format directly.
Log log(boost::format("foo %1% bar") % 42); // with Log(boost::format)
Log log((boost::format("foo %1% bar") % 42).str()); // with only Log(std::string)
Refer to Boost.Format documentation for details.
Two immediate possibilities come to mind. The first is to take advantage of std::string appending:
Log log(std::string("foo:") + bar);
The second is to make more log constructors that take additional parameters:
Log log("foo:", bar);
You really should consider using Boost.Log for your logging. Logging can be a complex thing; it's useful to get a fully formed implementation.
You can create a logging class that inherits from std::strstream.
class Mstream : public std::strstream
{
public:
Mstream() : std::strstream(Buffer = new char[BUFLEN], BUFLEN, ios::out);
ostream& endf(ostream& s);
void Write();
private:
char* Buffer;
};
Now you can log output as,
Mstream m;
m <<"Foo"<<s<<endf;
In endf(ostream& s) you can cast ostream to Mstream and call the Write(). In Write(), you format the output and print it to console or to a file.