Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows API and GetClassName()? Another name?

I have some code that has a dynamic-class system in C++ that has a member called GetClassName(), a rather harmless name one would imagine. However when included in a large project with Windows headers all hell broke loose. Apparently Windows uses a #define GetClassName (GetClassNameA or GetClassNameW) which screws up everything, and my virtual call tree became all messed up making me lose a day in stupid compiler debugging in the dark, trying to figure out what was wrong.

So besides the point that I'm cursing Microsoft for using such a horribly easy to clash name for a #define (I mean someone should honestly be shot for this!) I'm asking for 3 purposes.

  1. What's another good name for GetClassName() ?
  2. Is there anyway to fix this, so in the future, other developers of my code base won't suffer similar fate
  3. And for posterity when someone else encounters this similarly inexplicable error
like image 791
Robert Gould Avatar asked Dec 09 '22 21:12

Robert Gould


2 Answers

  1. ClassGetName()
  2. #undef GetClassName
  3. WinAPI is a C API. No namespaces. Some other platforms try to mitigate this by prefixing all symbol names, but eventually that falls apart as well. Best bet: if you're writing code that doesn't depend on the Windows Platform SDK headers, then don't #include them.
like image 151
Shog9 Avatar answered Dec 20 '22 07:12

Shog9


I would rename the method.

Of course one can say

#include <windows.h>
#undef GetClassName

but it is not clean, users of one's code should remember to write ::GetClassNameW when they call win32 function.

One can provide GetClassNameA and GetClassNameW methods in his class, but it's plain ugly.

I see two approaches : either lengthen or shorten the name:)

1) add a prefix for all functions in the subsystem, f.e TI_ (for type info):

TI_GetClassName() 
TI_GetBaseClass() 
TI_IsDerivedFromClass()
etc  

2) or put them into some IClass interface

interface IClass {
GetName();
GetBase(); 
IsDerivedFrom();
etc

and return that interface from single method,
so that GetClassName() becomes

GetClass()->GetName()
like image 27
eugensk Avatar answered Dec 20 '22 07:12

eugensk