- C++ class method conflicting with winapi functions
- Posted by zionz on April 2nd, 2008
Hello i'm using dev-cpp and i was having some strange linker errors in
my project, after a while i discovered that the problem was the member
functions of my class had the same name than existing winapi
functions, now i wonder if this is a problem of my c++ compiler or if
there is an way to avoid this problem?
For example this project produces the error (CreateFont() is a winapi
func):
//content of main.cpp:
#include <windows.h>
#include "ctest.h"
int main(){
CTest a;
a.CreateFont();
return 0;
}
//contents of ctest.h
class CTest{
public:
void CreateFont();
};
//contents of ctest.cpp
#include "ctest.h"
void CTest::CreateFont()
{
//some code here
}
- Posted by Sebastian G. on April 2nd, 2008
zionz wrote:
^^^^^^^^^^^^^^^^^^
There's your problem. You should name it CTest::CreateFont, anyway else the
global namespace is assumed, where the WinAPI function already resides.
- Posted by Alf P. Steinbach on April 2nd, 2008
* zionz:
Most Windows API functions are implemented as macros that expand to narrow
(byte) character version, CreateFontA, or Unicode UTF16 version, CreateFontW,
depending on the macro symbol UNICODE.
Assuming you haven't defined UNICODE: in your main program, where you include
<windows.h> and so have the CreateFont macro definition, CreateFont is expanded
to CreateFontA. In [ctest.cpp] however <windows.h> is not included, so there
you don't have a CreateFont macro, and CreateFont ends up as CreateFont. And
CreateFontA is not the same name as CreateFont.
You can avoid most of this problem by using lowercase initial character for
function names, i.e. createFont.
To avoid a similar problem (with the lowercase names min and max) you should
always define NOMINMAX before including <windows.h>.
Earlier it was also necessary to define STRICT, but with modern Windows headers
this symbol is now defined automatically for C++.
Cheers, & hth.,
- Alf
- Posted by Thomas J. Gritzan on April 2nd, 2008
zionz schrieb:
Posting the linker errors, at least in part, would help.
I guess your problem is, that <windows.h> defines some macros like:
#ifdef UNICODE
# define CreateFont CreateFontA
#else
# define CreateFont CreateFontW
#endif
So the member function CreateFont will be CreateFontA in the files that
have <windows.h> included, CreateFont in the others. This mismatch causes
the linker errors.
If you don't use the Windows API function CreateFont in your programm,
simply insert this before the class definition in the header, and tell me
if it works:
#ifdef CreateFont
# undef CreateFont
#endif
--
Thomas
http://www.netmeister.org/news/learn2quote.html
There are no bugs, and they have been fixed!
- Posted by zionz on April 2nd, 2008
Thank you all for the help, sry for not adding the linker error i was
getting, the error is:
[Linker error] undefined reference to `CTest::CreateFontA()'
I tried your suggestions, first declaring the func like this in the
class body:
void CTest::CreateFont()
wich had no effect, i was still getting the same error, then i tried
undefining CreateFont:
#ifdef CreateFont
#undef CreateFont
#endif
this effectively solved the problem, so i wonder if its safe to use
this approach to avoid the problem (i have about 4 functions
conflicting).
This happened because i developed the original program under linux,
later i decided to port it to windows so i was not aware that this
could happen
.
- Posted by Alf P. Steinbach on April 2nd, 2008
* zionz:
Not surprisingly, it was just nonsense advice.
Not if you want to use the CreateFont API function without writing CreateFontA
or CreateFontW.
Why don't you do as I suggested.
Cheers, & hth.,
- Alf
- Posted by zionz on April 2nd, 2008
On 2 abr, 20:21, "Alf P. Steinbach" <al...@start.no> wrote:
I know i just wanted to avoid having to rename the existing functions
since that funcs are used in lots of places... the program only uses
winsocks and when you include winsock.h it also adds windows.h thus
causing the problem.
Thnx again for your help.
- Posted by JussiJ on April 3rd, 2008
On Apr 3, 8:43*am, zionz <zion...@gmail.com> wrote:
That is because you are missing this line of code at
the top of your ctest.cpp file:
#include <windows.h>
Jussi Jumppanen
Author: Zeus for Windows IDE
http://www.zeusedit.com
- Posted by Ulrich Eckhardt on April 3rd, 2008
zionz wrote:
As others have pointed out, CreateFont is #defined to something else in
windows.h and therefore the effective content of your header depends on
whether windows.h was included before that or not.
Options:
1a. #undef the macro in the header
This has the drawback that any code that includes the header and lateron
tries to use the win32 function/macro will fail to compile. Note that you
can still access the two CreateFontA and CreateFontW functions directly by
their name, which is often a good choice.
1b. Same as 1a but you create a global inline replacement function for the
win32 macro. Since function behave properly as opposed to macros, this
would solve your problem, too.
2. always include windows.h
This is pretty simple. However, it will effectively rename your function to
whatever windows.h defines its macro to, which might make a difference when
you are building a DLL because then it also affects the exported symbols.
3. rename your function
Obviously, if it doesn't conflict with the win32 API there won't be a
problem.
4. hide the function from the preprocessor
I think that all you need to do is put the name in brackets, at every place
that it should refer to your function.
I'd go for 1a and maybe switch to 1b if things start falling apart.
Uli
--
Sator Laser GmbH
Geschäftsführer: Michael Wöhrmann, Amtsgericht Hamburg HR B62 932