tags:

views:

128

answers:

3

I have a project that uses two third party libraries, both of which make use of TCHARs in their header files. Unfortunately one library is complied as multi-byte (call it library a), and the other is compiled as Unicode (call it library b).

Now the way I understand it is that TCHAR is replaced by the precompiler with either wchar or char depending on the build options. So when library a was compiled any method that takes a parameter of type TCHAR was set to expect a parameter of type char, and methods in library b are set to expect a parameter of type wchar.

Unfortunately my consuming application has to pick a character set too. If I pick Unicode then the header file I have included for library a tells me that the method wants a wchar, because when I compile the TCHARs in the header they are interpreted as wchars. This includes TCHARS defined inside of structures. I have confirmed this behavior in practice, when I allocate and pass a TCHAR buffer I get back garbage because it fills my wchar buffer with multi-byte data.

My questions are: Is there a clean way to consume both of these libraries in the same application? Am I maybe doing something wrong with how I'm using these libraries?

A: 

I think your best option is to choose either library a or library b (we'll say library a for this example) way of doing it. And then when you include library b header files, make sure you #define/#undef whatever library b was compiled with. Then you have to make sure you convert between library a and library b anytime they use the same data.

It would really be best if you could get them compiled the same way. Otherwise it's going to be very messy.

jcopenha
+4  A: 

Assuming you're not using too many class/function in either one of these libraries, I would wrap one of the library completely. Let's say if you decided to use mbc in your app and wrap library b (unicode), your wrapper header file can use wchar_t instead of TCHAR so #define will not affect your interface. Inside your wrapper's cpp file where you #include library b's headers, you #define TCHAR to match library b. No code other than your wrapper should be allowed to see library b.

If you're using more than a few class/function in both of these libraries, maintaining the wrapper code will quickly become a problem of its own.

Shing Yip
Thanks for your answer, that's the direction I am leaning. I'm going to go out on a limb and ask what might be a dumb question. What's the advantage of having a wrapper versus just editing the header file for the library so that it matches the compiled definitions of the structures and exported functions? I'm imagining this being mostly as easy as doing a search and replace of TCHARs. Am I oversimplifying it?
MichaC
xtofl points out one advantage below: you can convert to and from multi-byte in the wrapper. I suppose I'm mostly interested in feedback on whether the find/replace would even work.
MichaC
Replacing TCHARs with char/wchar_t in your library header file will only work as long as you replace ALL of them including the header files included via #include in your library header files. Depends on your library, that may include some standard/system files. The other drawback is when you get a new version of the library what do you do? Search and replace again?
Shing Yip
+1  A: 

As Shing Yip suggested, better wrap the difference in an API of your own. This makes your source code independent of it.

The wrapping API then has to convert characters from your encoding to the library's. On windows, I you have functions called WideCharToMultiByte and the like.

xtofl