How do I use GLADcallback? - c++

I'm using glad to generate OpenGL bindings, and have generated a debug build which includes the following:
// this symbol only exists if generated with the c-debug generator
#define GLAD_DEBUG
typedef void (* GLADcallback)(const char *name, void *funcptr, int len_args, ...);
/*
* Sets a callback which will be called before every function call
* to a function loaded by glad.
*
*/
GLAPI void glad_set_pre_callback(GLADcallback cb);
/*
* Sets a callback which will be called after every function call
* to a function loaded by glad.
*
*/
GLAPI void glad_set_post_callback(GLADcallback cb);
The documentation gave an example how to define this callback, which looks like this:
void _post_call_callback_default(const char *name, void *funcptr, int len_args, ...) {
GLenum error_code;
error_code = glad_glGetError();
if (error_code != GL_NO_ERROR) {
fprintf(stderr, "ERROR %d in %s\n", error_code, name);
}
}
What I don't understand is how I'm supposed to access the varargs. I'm guessing that they are the values that are passed to the OpenGL function, and thus can be any type. However, I must specify the type to va_arg in order to access the values.
I feel that the parameter len_args is hinting that there is some way to iterate over the varargs, but I don't understand how it's supposed to be used without knowing the types. How are they meant to be used?

You have the source code of glad.c whenever the glad_set_post_callback function is called. There you can see that the parameters depends on which function was called. So I think you need to check the name/funcptr parameter.
For example if glEnable was called then you have:
void APIENTRY glad_debug_impl_glEnable(GLenum arg0) {
_pre_call_callback("glEnable", (void*)glEnable, 1, arg0);
glad_glEnable(arg0);
_post_call_callback("glEnable", (void*)glEnable, 1, arg0);
}
which means that the first parameter is a GLenum. See this question an-example-of-use-of-varargs-in-c on how to use variable arguments:
It would be something like this (not tested):
void _post_call_callback_default(const char *name, void *funcptr, int len_args, ...) {
GLenum error_code;
error_code = glad_glGetError();
if (error_code != GL_NO_ERROR && funcptr == (void*)glEnable /* or strcmp(name,"glError") == 0*/) {
va_list ap;
va_start(ap, len_args);
GLenum arg0 = va_arg(ap, GLenum);
va_end(ap);
printf("Called glError(%d) with Error %d\n", arg0, error_code);
}
}
You can so decide for which functions you want a better debug log. I am not aware if there is already some free code that gives a better debug output.
Maybe it's better to compare funcptr with the pointer to glEnable instead of comparing the string name with "glError". I didn't tested it. The code above is just an example, I would write it differently.

Related

How to register callback with variadic arguments and pass a value

could you please help in following.
I have callback function definition in the 3rd lib header:
#ifdef __cplusplus
extern "C" {
#endif
typedef int (*SOCK_CLBK)(int, short, unsigned char*, int, ...);
#ifdef __cplusplus
}
#endif
And I define my callback in the following way:
header file:
template<typename T>
int ReadTCP(int socket, short code, unsigned char* msg, int received, T a);
cpp file:
template<>
int ReadTCP(int socket, short code, unsigned char* msg, int received, int a)
{
return 0;
}
and register my callback in the code:
server->registerCallback(port, (SOCK_CLBK)(ReadTCP<int>),maxTCPsize);
This works fine, and the callback is triggered when needed.
The problem is, the "int a" contains random values every time.
how to register a callback and pass my own specific value for example 100000, that will occur in the callback in "a"?
Something like
server->registerCallback(port, (SOCK_CLBK)(&std::bind(ReadTCP<int>,_1,_2,_3,_4, 100000),maxTCPsize);
but this does not work (triggers runtime exception).
What I am doing wrong?
lib header:
#include "CSocket.h"
#ifndef WIN32
#include <pthread.h>
#else
#include <windows.h>
#include <WinSock.h>
#endif
#define CPP_TCP_MAX_CLIENTS 17
#define CPP_TCP_MAX_SIZE 1500 //In accordance with MTU definitoins
class DLLCPP_API CSERVER {
public:
/**
* default constructor
*/
CSERVER ();
/**
* default destructor
*/
virtual ~CSERVER ();
/**! \fn int Create(unsigned int uiPort, bool bClbk);
* \brief creates singleton socket listener
* creates singleton socket listener, which is invoked within dedicated thread
* if bClbk is true, otherwise within the main thread.
* \param uiPort socket listener port
* \param fnClbk call-back function address. if not NULL then callback mode of operation. otherwise normal.
* \return 0 on success, error id otherwise.
*/
int registerCallback(unsigned int uiPort, SOCK_CLBK fnClbk=NULL, int iMsgMaxSize=512)throw (CMException);
….
…
Send()…
….
...
protected:
#ifndef WIN32
friend void* _fnTCPClbkThread(void *); //call-back argument for pthread_create within RunClbkThread.
#else
friend DWORD WINAPI _fnTCPClbkThread( LPVOID lpParam );
#endif
/**! \fn int IsPending(int iSock, bool& bFail)
* \brief check pending connection on a non blocking socket
* actuall checks for errors and whether or not connection is ready for write operation.
* \param iSock client socket connection to check.
* \return: OK (0) if iSock ready for write operation or ERROR otherwise (still pending for instance)
*/
int IsPending(int iSock)throw (CMException);
int RunClbkThread();
int CreateClbk()throw (CMException);
void ClbkThread();
private:
typedef void (CSERVER::*PCLBKTHREAD)(void *);
PCLBKTHREAD _pThreadClbk;
int _iServerSock;
int _iSock;
SOCK_CLBK _fnClbk;
unsigned int _uiPort;
int _iAddrLen;
bool _bClbkThreadAlive;
int _iClientConnectionsArr[CPP_TCP_MAX_CLIENTS];
int _iMsgMaxSize;
struct sockaddr_in _saddConnect ;
#ifdef WIN32
WSADATA m_wsaData;
HANDLE _thread;
#else
pthread_t _thread;
#endif
};
Look at function registerCallback
From which I can deduct that the class does not store any user data to be passed later as a callback parameter... Why do they have variadic template then - no idea.
First, your code with ReadTCP function template is incorrect. SOCK_CLBK is a type of a function pointer that has an ellipsis at the end of its argument list, which is different from int (or any other type) that ReadTCP<int> has. The compiler does not fail to compile because you explicitly convert the pointer to ReadTCP<int> to SOCK_CLBK, but the call fails at runtime (you either receive a random value in the int a argument or crash).
Your second piece of code with std::bind is also wrong because std::bind returns a function object, not a pointer to function. The function object has operator(), so it can be called like a function, but it cannot be converted to a function pointer (for one, because the object also contains data, like the arguments you bound).
You must define a function that accepts a variable number of arguments (i.e. has an ellipsis at the end of its argument list) and pass that function as the callback. In that function, you can process the passed arguments and possibly invoke other specialized functions in your code, like ReadTCP.
int ReadTCPCallback(int socket, short code, unsigned char* msg, int received, ...)
{
std::va_list args;
va_start(args, received);
// Use variable arguments here, using va_arg. Consult with the API
// documentation to know what arguments are expected here. For the sake
// of this example, let's assume an int argument is passed.
int n = va_arg(args, int);
int res = ReadTCP(socket, code, msg, received, n);
// Always call va_end before returning once you're done with va_list
va_end(args);
return res;
}
If you want to use function objects with this API then you will have to find a way to pass a pointer to data through the third party library to the callback. That data will contain the bound parameters and other state pertinent to the call. Refer to the documentation of that third party library as to how to pass user's data to the callback.
If the API does not support passing user's data (which would make it a rather poorly designed API), you could associate the data with some handle returned by the API that corresponds to your state. For example, you could maintain a global std::map to map the socket file descriptor (int) to a pointer to your data related to that socket or connection.

Define (and declare and use) global variables from function through macros

I’m trying to reimplement in a backward-compatible way the RobotC API from C (although some details such as automatical inclusion of stdbool, optional parameters, references, I/O through “array”/subscript notation value/assignment, etc. would better fit C++ and some issues may be easier to solve in C++…). This one includes void startTask(void TaskID, short nTaskPriority) and void stopTask(void TaskID) to enable multithreading.
TaskID is meant to directly be the name of the function to run in a new thread. So no thread number variable there, only the global-scope function name. I first tried to implement something near this using macro identifier concatenation and external variables, but I can’t define a global variable from inside a function (using extern would result in a declaration rather than a definition, and a definition in a function is by default in local scope), so I end up with something that works only in the same scope (or stopping from an inner scope would work, but not the other way).
How could I do something alike? for example how to define (for example using some complex macro trick, a gcc extension (though I’d prefer to stay standard if possible, but wouldn’t bother too much if a such feature required gcc), or whatever?) a global, preferably multi-file, namespace-unique, made-up variable, for storing the pthread id?
#include <stdlib.h>
#include <pthread.h>
#include <stdarg.h>
#include <sched.h>
#include "misc.c"
const short kHighPriority = 255;
const short kLowPriority = 0;
const short kDefaultTaskPriority = 7;
/* void startTask(void TaskID,
short nTaskPriority = kDefaultTaskPriority) */
pthread_t
startTask (task (*TaskID)(void*), short nTaskPriority)
{
pthread_attr_t attr;
pthread_t thread;
struct sched_param param;
const int policy = sched_getscheduler(0),
sched_high_prio = sched_get_priority_max(policy), // 19,
sched_low_prio = sched_get_priority_min(policy), // -20,
sched_range_prio = sched_high_prio - sched_low_prio;
pthread_attr_init (&attr);
pthread_attr_getinheritsched(&attr, PTHREAD_INHERIT_SCHED);
pthread_attr_getschedparam (&attr, &param);
param.sched_priority = -(((nTaskPriority
- kLowPriority) * sched_range_prio
/ kHighPriority) + sched_low_prio);
pthread_attr_setschedparam (&attr, &param);
pthread_create (&thread, &attr, (void*) TaskID, NULL);
return thread;
}
void
stopTask (pthread_t thread)
{
pthread_cancel(thread);
}
void
stopAllTasks ()
{
exit(0);
}
#define startTask(task, priority) \
static pthread_t task##_thread = startTask(task, priority)
#define stopTask(task) \
stopTask(task##_thread)
I’d prefer, ideally, to solve this problem without external (that is, non-standard) libraries, at compile time, with C instead of C++, standard (C11 doesn’t disturb me) if possible, in this order (!gcc-specific || ! cxx || compile-time || stdc).
That is, except if something else is found, I’m okay with C++, even more with GNU extensions and totally okay with C/C++11 to solve this problem at compile-time instead of runtime, for instance (though my reimplementation seems mostly standard to me, global-scope multithreading requiring GNU doesn’t seems too much).
I would use a dictionary. A dictionary associates keys with values. The key is this case would by the task name, converted to a string. And the value would be the thread ID from pthread_create.
The dictionary itself could be implemented any way you like: hash table, binary tree, linked list, or even an array. The dictionary interface consists of three functions: Add(), Find(), and Remove().
To use the dictionary, the startTask and stopTask macros convert the function name to a string using the # operator. The string is then passed to the StartTask and StopTask functions and used as the key in the dictionary.
Here's some sample code that demonstrates the concepts:
#include <stdio.h>
#include <stdbool.h>
#include <pthread.h>
#define startTask(task, priority) startTask(#task, task, priority)
#define stopTask(task) stopTask(#task)
void dictionaryAdd(char *key, pthread_t threadID)
{
printf("Adding key: %s\n", key);
// add the key with its associated threadID to the dictionary
}
bool dictionaryFind(char *key, pthread_t *threadID)
{
printf("Finding key: %s\n", key);
// find the key in the dictionary and get the associated threadID
*threadID = 0;
return true;
}
void dictionaryRemove(char *key)
{
// remove the key and associated value from the dictionary
printf("Removing key: %s\n", key);
}
void startTask(char *name, ...)
{
pthread_t threadID = 0;
pthread_create(&threadID, ...);
dictionaryAdd(name, threadID);
}
void stopTask(char *name)
{
pthread_t threadID;
if (dictionaryFind(name, &threadID))
{
pthread_cancel(threadID);
dictionaryRemove(name);
}
}
void *foo(void *arg)
{
return NULL;
}
int main(void)
{
startTask(foo, 10);
stopTask(foo);
}
The output from the code:
Adding key: foo
Finding key: foo
Removing key: foo

Trouble retrieving and storing pointers to OpenGL functions manually

I have some trouble retrieving and storing manually the pointers to OpenGL functions, here is a "simplified snippet" version of my code :
#ifdef WIN32
#include <windows.h>
#endif
#include <GL/gl.h>
class CGLManager
{
public:
// Manager functions
bool GetAnyGLFuncAddress( const char *_cName, void *_pFunc );
bool LoadFunctions( void );
// OpenGL functions
void (APIENTRY *glBegin)( GLenum mode );
void (APIENTRY *glEnd)( void );
void (APIENTRY *glVertex3f)( GLfloat x, GLfloat y, GLfloat z );
private:
#ifdef WIN32
HMODULE m_hLib; // opengl32.dll
#else
void *m_hLib; // libGL.so
#endif
};
And here's the source :
extern CGLManager gGL;
// GetAnyGLFuncAddress - Attempt to retrieve the OpenGL function named "_cName" and store it in "_pFunc", returns true if success or false otherwise
bool CGLManager::GetAnyGLFuncAddress( const char *_cName, void *_pFunc )
{
#ifdef WIN32
// Similar to https://www.opengl.org/wiki/Load_OpenGL_Functions#Windows
_pFunc = (void *)wglGetProcAddress( _cName );
if ( _pFunc == 0 || (_pFunc == (void *)0x1) || (_pFunc == (void *)0x2) || (_pFunc == (void *)0x3) || (_pFunc == (void *)-1) )
_pFunc = (void *)GetProcAddress( m_hLib, _cName );
#else
// TODO: Test this
// According to some websites, NVIDIA drivers prefer the ARB implementation over the core one
_pFunc = (void *)glXGetProcAddressARB( _cName );
if ( _pFunc == 0 || (_pFunc == (void *)0x1) || (_pFunc == (void *)0x2) || (_pFunc == (void *)0x3) || (_pFunc == (void *)-1) )
_pFunc = (void *)glXGetProcAddress( _cName );
#endif
return (_pFunc != NULL);
}
// LoadFunctions - Attempt to retrieve all used OpenGL functions, returns true if all of them were retrieved or false if there is a single failure
bool CGLManager::LoadFunctions( void )
{
if ( !(GetAnyGLFuncAddress( "glBegin", &gGL.glBegin )) )
return false;
if ( !(GetAnyGLFuncAddress( "glEnd", &gGL.glEnd )) )
return false;
if ( !(GetAnyGLFuncAddress( "glVertex3f", &gGL.glVertex3f )) )
return false;
return true;
}
Here's how my manager work in general : it first check which renderer the game's engine uses (Software, OpenGL or Direct3D), if it's not OpenGL, then we stop getting any further. Otherwise, we load the library (opengl32.dll or libGL.so) and we check if it's good or not (again, if failed, we stop), we retrieve and store the pointers to OpenGL's functions (glBegin, glEnd, glVertex3f) with the LoadFunctions method and we return if everything's fine or something wrong happened.
Now the problem : the GetAnyGLFuncAddress method retrieve successfully OpenGL functions (in other words, glBegin will return true, glARandomMethodThatDontExist will return false) but for some reason, gGL.glBegin (and it's "friends") in LoadFunctions doesn't get updated and it will be always NULL causing a crash.
I have been trying for hours to find out a solution by searching on Internet and on StackOverflow but I haven't found any answer that can give me the solution to the problem.
In many websites and answers I've found on StackOverflow, a lot of people suggested to use an OpenGL loading library like GLEW and even the OpenGL wiki recommend it. However, due to the nature of the environment I'm working on, I can't use those kind of libraries and neither I can't use OpenGL functions directly, I know I'm going through the painful way by doing everything manually but I have no other choice.
Thank you for your answers.
bool CGLManager::GetAnyGLFuncAddress( const char *_cName, void *_pFunc )
This is just common, broken C++. _pFunc is a void*. The pointer is the value. Changing the value of _pFunc will not change the value of the variable passed in.
You should either just return the pointer (with NULL representing the failure condition), or _pFunc should be a void**. That will likely require a cast from the caller though, and GetAnyGLFuncAddress would need to do *_pFunc = to set the value.
If you're going to return the function pointer, then you need to cast the returned void* to the appropriate function pointer type before storing it. This is why you often see OpenGL loaders use typedefs for function pointer types.
typedef void (APIENTRY *(PFN_GLBEGIN))( GLenum );
...
PFN_GLBEGIN glBegin;
...
glBegin = static_cast<PFN_GLBEGIN>(GetAnyGLFuncAddress("glBegin"));
Something like that.
Forgetting about what your ultimate goal is, I see basic C++ mistakes.
Let's cut out all of the code that is irrelevant and focus on this:
bool CGLManager::GetAnyGLFuncAddress( const char *_cName, void *_pFunc )
{
_pFunc = (void *)wglGetProcAddress( _cName ); // <-- This sets the local pointer
//...
}
Then you call the above like this:
bool CGLManager::LoadFunctions( void )
{
if ( !(GetAnyGLFuncAddress( "glBegin", &gGL.glBegin )) )
return false;
}
You're passing the address in the second argument, but inside the function GetAnyGLFuncAddress, you're not updating the value so that the new value is reflected back to the caller. You're setting the local value instead, thus gGL.glBegin (and all the other addresses from the other two calls), will not be set.
Inside of GetAnyGLFuncAddress, I would have expected this to work:
bool CGLManager::GetAnyGLFuncAddress( const char *_cName, void *_pFunc )
{
*_pFunc = (void *)wglGetProcAddress( _cName ); // <-- Note the *
//...
}
And any subsequent usage of pFunc inside of GetAnyGLFuncAddress also should reflect the dereferenced value.
Another solution (and since this is C++), you can forego the void * C-like coding and make the function a template that takes a function pointer type as the template argument:
template <typename FnPtr>
bool CGLManager::GetAnyGLFuncAddress( const char *_cName, FnPtr* _pFunc )
{
*_pFunc = reinterpret_cast<FnPtr>(wglGetProcAddress( _cName ));
//...
}
Since the type is now FnPtr*, whatever you pass in will automatically have FnPtr be of that type. No more void * (except for the return value of wglGetProcAddress, which is casted).
*gl*GetProcAddres is specified only for returning entry point addresses for extended functionality. It is not required that it returns addresses for functions found in the operating systems OpenGL ABI requirements (OpenGL-1.1 for Windows, OpenGL-1.2 for Linux Softare Base (LSB) 4, OpenGL-2.1 for LSB-5).
In general if your program binary is directly linked to the API library (stub) (in contrast to using a loader that loads the API library (stub) at runtime, dynamically), it's quity silly to retrieve functions being part of the OS's OpenGL ABI contract with *gl*GetProcAddress as these function are available through the regular API library anyway. wglGetProcAddress is exported alongside OpenGL-1.1 functions as is glXGetProcAddress exported alongside all OpenGL-1.2 functions (at least), so if your program sees the *GetProcAddress functions it also sees the other OpenGL functions.
The only reason to load all OpenGL symbols through GetProcAddress is if you load opengl32.dll with LoadLibrary or libGL.so with dlopen.

Using var_arg to pass parameters for function calls

I am writing an adapter to combine two APIs (one in C and another in C++).
If a function is called on the one API I need to pass the callers ID and the function's arguments to an adapter and call the according function with this information passed.
Now aparently they can not be mapped directly as one interface requires C++ compilation and the name mangling would screw the other so that is why I am using a set of adapters in the first place.
As the number of arguments varies, I looked up variadic functions and found the idea pretty useful, however I am operating on POD only and have to deal with structs, enums and a lot of different arguments per call, which might need to be put back into a struct before feeding it to the target function.
Every example I stumbled upon was far simpler and involved mostly arithmetic operations like summing stuff up , finding largest numbers or printing. Mostly done with for loops on the var_list.
Maybe I got stuck on the idea and it won't work at all, but I am just curious...
Say I wanted to assign the arguments from the list to my target functions parameters (the order of the arguments passed is the correct one), what would be a good way?
BOOL Some_Function(
/* in */ CallerId *pObjectId,
/* in */ someDataType argument1 )
{
BOOL ret = Adapter_Call(pFunction, pObjectId, argument1);
return ret;
}
and so once I made it to the right adapter I want to do
BOOL Adapter_Call(*pFunction, *pObjectId, argument1, ...)
{
va_list args;
va_start(args, argument1);
/*go over list and do `var_list[i] = pFunctionArgList[i]` which is
of whatever type so I can use it as input for my function */
va_end(args);
pObjectId.pFunction(arg1,...,argn);
}
Can I access the input parameters of a function to perform assignments like this?
Has anyone done something like this before? Is there a conceptual mistake in my thinking?
All I found on the net was this, http://www.drdobbs.com/cpp/extracting-function-parameter-and-return/240000586but due to the use of templates I am not sure if it wouldn't create another problem and so in the end implementing an adapter for each and every single functioncall may be simpler to do.
A SO search only returned this: Dynamic function calls at runtime (va_list)
First, you should heed Kerrek's advice about extern "C". This is C++'s mechanism for giving an identifier C linkage, meaning that the name won't be mangled by the C++ compiler.
Sometimes, and adapter still needs to be written for a C++ interface, because it manipulates objects that do not map to a C POD. So, the adapter gives the C interface a POD or opaque pointer type to manipulate, but the implementation of that interface converts that into an C++ object or reference and then calls the C++ interface. For example, suppose you wanted to provide a C interface for C++ std::map<int, void *>, you would have a common header file in C and C++ that would contain:
#ifdef __cplusplus
extern "C" {
#endif
struct c_map_int_ptr;
// ...
// return -1 on failure, otherwise 0, and *data is populated with result
int c_map_int_ptr_find (struct c_map_int_ptr *, int key, void **data);
#ifdef __cplusplus
}
#endif
Then, the C++ code could implement the function like:
typedef std::map<int, void *> map_int_ptr;
int c_map_int_ptr_find (struct c_map_int_ptr *cmap, int key, void **data) {
map_int_ptr &map = *static_cast<map_int_ptr *>(cmap);
map_int_ptr::iterator i = map.find(key);
if (i != map.end()) {
*data = i->second;
return 0;
}
return -1;
}
Thus, there is no need to pass the arguments passed via the C interface through a variable argument adapter. And so, there is no need for the C++ code to tease out the arguments from a variable argument list. The C code calls directly into the C++ code, which knows what to do with the arguments.
I suppose if you are trying to implement some kind of automated C adapter code generator by parsing C++ code, you could think that using variable arguments would provide a regular mechanism to communicate arguments between the generated C code interface and the generated C++ adapter code that would call the original C++ interface. For such a scenario, the code for the above example would look something like this:
// C interface
typedef struct c_map_int_ptr c_map_int_ptr;
typedef struct c_map_int_ptr_iterator c_map_int_ptr_iterator;
//...
c_map_int_ptr_iterator c_map_int_ptr_find (c_map_int_ptr *map, int key) {
c_map_int_ptr_iterator result;
cpp_map_int_ptr_adapter(__func__, map, key, &result);
return result;
}
// C++ code:
struct cpp_adapter {
virtual ~cpp_adapter () {}
virtual void execute (va_list) {}
};
void cpp_map_int_ptr_adapter(const char *func, ...) {
va_list ap;
va_start(ap, func);
cpp_map_int_ptr_adapter_method_lookup(func).execute(ap);
va_end(ap);
}
//...
struct cpp_map_int_ptr_find_adapter : cpp_adapter {
void execute (va_list ap) {
map_int_ptr *map = va_arg(ap, map_int_ptr *);
int key = va_arg(ap, int);
c_map_int_ptr_iterator *c_iter = va_arg(ap, c_map_int_ptr_iterator *);
map_int_ptr::iterator i = map->find(key);
//...transfer result to c_iter
}
};
Where cpp_map_int_ptr_adapter_method_lookup() returns an appropriate cpp_adapter instance based on a table lookup.

How to overload printf or cout

I use cout statements in my program for debugging purposes. I would like to make a function that works like it, or works like printf, but is sensitive to a global variable. If this global variable is true, then it will print to screen. If it is false, then it won't print anything. Is there already a function like this? If not, then how can it be made?
Something like this:
int myPrintf(const char* format, ...)
{
if (globalCheck == 0)
return 0
va_list vl;
va_start(vl, format);
auto ret = vprintf(format, vl);
va_end(vl);
return ret;
}
va_start and va_end take the arguments in the ... and encapsulate them in a va_list. with this va_list you can then the vprintf which is a variant of printf designed exactly for this need.
Side note - usually it is bad practice to use global variables. A better thing to do is to encapsulate it in a class like this -
class ConditionalPrinter {
public:
ConditionalPrinter() : m_enable(true) {}
void setOut(bool enable) { m_enable = enable; }
int myPrintf(const char* format, ...);
private:
bool m_enable;
}
and then to check m_enable instead of the global variable.
Usage of this looks like this:
ConditionalPrinter p;
p.myPrintf("hello %d", 1); // printed
p.setOut(false);
p.myPrintf("hello2 %d", 1); // not printed
....
Don't write it yourself. Doing it right is much harder then you think. Even harder when you need threads and efficiency. Use one of existing logging libraries like:
glog: http://code.google.com/p/google-glog/ (I prefer this - it is lightweight and do what it needs to do)
Log4cpp http://log4cpp.sourceforge.net/ (powerful and configuration compatible with popular java logging)
... add your favorite to this wiki
As someone else said, there are several good logging frameworks available. However, if you want to roll your own, the first thing to note is that cout isn't a function, it's a stream. The function is operator<<. What you can do is something like the following:
/* trace.h */
extern ostream debug;
void trace_init();
void trace_done();
/* trace.cpp */
#include "trace.h"
ostream debug(cout.rdbuf());
static ofstream null;
void trace_init()
{
null.open("/dev/null");
if(output_is_disabled) { // put whatever your condition is here
debug.rdbuf(null.rdbuf());
}
}
void trace_done()
{
null.close();
}
You might have to adjust a bit if you're on a platform without /dev/null. What this does is let you write
debug << "here's some output << endl;
and if you have the output enabled, it will write to cout. If not, it will write to /dev/null where you won't see anything.
For that matter, you could just set cout's rdbuf to somewhere where you won't see that output, but I would find that to be a really bad idea. Creating new streams gives you a lot more flexibility in controlling your output.