2008 Jan 27 - Sun
Symbol Clash Between VC++ oledb.h and Berkeley DB db.h
When attempting to use Berkeley DB4 in a Microsoft Visual Studio 2005 C++ project, the
symbol DBTYPE is found in both Microsoft's oledb.h and Berkeley DB4's db.h. It is really
hard to get rid of oledb.h as it is buried somewhere in the depths of the stdafx.h
precompiled header file.
In one of the forums, a suggestion was made to wrap the Berkely DB4 header file db_cxx.h
in a namespace. That worked somewhat to remove the name clash, but it resulted in a link
error of not being able to find the namespaced symbol in the dll file. I wasn't sure what
was needed to resolve that bit of a naming/link-resolution problem.
Elsewhere, in another forum posting, there was a suggestion of using an #undef DBTYPE.
That didn't appear to work either. I think this is because DBTYPE is a 'typedef' rather
than a simple #define. I suppose I could have tried to change the typedef to a #define.
Instead, I made a copy of oledb.h as oledb.original.h, and modified the oledb.h file. I
changed all references of DBTYPE to MS_DBTYPE and rebuilt the project. The project compiled
and linked fine.
Of course, if I need to use oledb.h in the future, something I doubt very much, but one
never knows, I'll have to figure something out to maintain code compatibility.
I'm sure there is a more elegant solution. If someone has encountered it, please email a
solution to me and I'll post it.
[/OpenSource/Programming]
permanent link
C++ Override std::cout, std::cerr Streams
C# has a handy method of redirecting Console output. In the first place, C# has a
System.Console library for catching all console based output. The Console.SetIn and
Console.SetOut methods can then be used to redirect input/output from/to local application
based routines.
In C on a Linux/Unix system one can use popen(), as described in question 19.30 of the
comp.lang.c FAQ. If you
cruise through the FAQ, other methods are discussed and critiqued.
extern FILE *popen();
sprintf(cmdbuf, "sort < %s", datafile);
fp = popen(cmdbuf, "r");
/* ...now read sorted data from fp... */
pclose(fp);
Some have suggested using the freopen() stdio function call to
redirect stdout to a file.
I havn't seen an example to get the stream back into the program though.
In C++, when using the Standard Templated Libraries (STL), one encounters the std::cout
and std::cerr streams for standard console output.
C++ streams are generic and, after a fashion, interchangeable. Each stream type has a
std::streambuf, which can be redirected. Be aware the streambuf is a C++ construct, and
therefore
won't catch stuff done with a printf or similar. A pipe may help for the printf problem (I
havn't looked into that), but a pipe isn't necessary for the streambuf solution.
A simplistic mechanism for switching streambufs is found in a
Borland CPP Builder Forum. An example there does show a good mechanism
for saving the old streambuffer before redirecting to the new one. The problem with the
posted example is that one has to come back to the streambuf and manually extract what was
there. A better solution would do a proper override and automatically process the arriving
characters.
I saw in a few places there people were trying to override endl or << operators.
That isn't quite correct either.
Probably the best description on how to do a proper override is located in a recent blog
entry from Sean Middleditch in a post called:
Creating Custom C++ Output Streams. His examples build a simple override
and then add additonal features on to improve the solution.
// from Sean Middleditch's site
// your log file, lazily declared as a global
ofstream logfile;
// logbuf forwards all output to cerr and logfile
class logbuf : public streambuf {
private:
// write a string s of length n to standard
// error and a log file
int xsputn (char_type* s, streamsize n) {
cerr.write(s, n);
logfile.write(s, n);
return n;
}
};
int main () {
// open our log file
logfile.open("mylog.txt", ios::app);
// create our log stream
ostream log(new logbuf());
// be friendly
log << "Hello, World!" << endl;
return 0;
}
For another perspective on the solution, Cay S. Horstmann wrote an article regarding
Extending the iostream
library. Further down in that article is an example for 'Routing stream output to a
debug window'.
Some further background on IOStreams and Stdio can be found in a Dr. Dobbs article by
Matthew H. Austern called
The Standard Librarian: IOStreams
and Stdio.
[/OpenSource/Programming]
permanent link
|