[FreeImage] Utilities.h unresolved external if Windows.h is included above it.

Started by
8 comments, last by FantasyVII 6 years, 7 months ago

Hi,

I'm using the FreeImage library to load images into my game engine. However, I have a small problem. There is a header file called Utilities.h and it contains a function called SwapRedBlue32. My problem is that if I include Windows.h at the very top of my  ImageLoader class and then include FreeImage headers after it I get an unresolved external error. The linker will not be able to link to the SwapRedBlue32 function. If I don't include Windows.h everything seems to work just fine. If I include Windows.h at the very bottom (after the FreeImage header files) I get 'HANDLE': undeclared identifier and many other windows related things become undeclared.

I have no idea how to fix this. I really need both Windows.h and this function. How do I even begin to try to fix this? I looked at Utilities.h and FreeImage.h and I can't seem to figure out how to fix this.

here is the error


error LNK2019: unresolved external symbol "int __cdecl SwapRedBlue32(struct FIBITMAP *)" (?SwapRedBlue32@@YAHPEAUFIBITMAP@@@Z) referenced in function "public: static unsigned char * __cdecl BF::IO::ImageLoader::Load(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,unsigned int *,unsigned int *)" (?Load@ImageLoader@IO@BF@@SAPEAEAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEAI1@Z)

 

Advertisement

This is a linker error, which means it isn't a problem of how your headers are set up. Make sure you have included all the required .cpp files in your project and they are all up to date.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This is why this makes zero sense to me.

I have FreeImage compiled as a static lib file and it is linked into my project just fine. If I don't include the Windows.h header file, my engine compiles and links and even runs and works perfectly. But the second I include Windows.h header in the same source file I have FreeImage in, I get the link error which makes zero sense to me.

 


//Link error
#include <Windows.h>
#include "FreeImage/FreeImage.h"
#include "FreeImage/Utilities.h"
  
//-----------------------------------------

//'HANDLE': undeclared identifier
#include "FreeImage/FreeImage.h"
#include "FreeImage/Utilities.h"
#include <Windows.h>
  
//-----------------------------------------
//Works and runs perfectly fine.
#include "FreeImage/FreeImage.h"
#include "FreeImage/Utilities.h"

 

Did you build the .lib with the same configurations as your main project? I.e. did you #include <windows.h> before Freeimage.h and Utilities.h there?

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

You mean if I try to #include <windows.h> inside the source code of FreeImage? If I do that I get a bunch of errors and the FreeImage lib will not compile.

Sounds like a macro is interfering with your build. Try #define WIN32_LEAN_AND_MEAN as well as #define NOMINMAX just to be safe.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

That didn't help :(

This is super frustrating :(

Maybe I should just switch to another library. uhh...

Did you add the following to your code anywhere?


#define FREEIMAGE_LIB

 

9 hours ago, Styves said:

Did you add the following to your code anywhere?



#define FREEIMAGE_LIB

 

i did.

 

ok, here it goes. This took me two days of trying random things and looking at the FreeImage source code. I can't believe I actually made this work. I'm actually a bit proud of myself right now.:) Anyway, I finally fixed this. although I'm still not sure why this fix is needed when including windows.h file. Why this wasn't an issue before including windows.h?

 

anyways, here it is.

So if you look at the "Utilities.h" file you will see this


//FreeImage.h
#define DLL_CALLCONV __stdcall
#define DLL_API __declspec(dllexport)

//----------------------------------------

//Utilities.h
#if defined(__cplusplus)
extern "C" {
#endif

DLL_API FIBITMAP * DLL_CALLCONV FreeImage_AllocateHeaderT(BOOL header_only, FREE_IMAGE_TYPE type, int width, int height, int bpp FI_DEFAULT(8), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0));

DLL_API FIBITMAP * DLL_CALLCONV FreeImage_AllocateHeader(BOOL header_only, int width, int height, int bpp, unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0));

DLL_API FIBITMAP * DLL_CALLCONV FreeImage_AllocateHeaderForBits(BYTE *ext_bits, unsigned ext_pitch, FREE_IMAGE_TYPE type, int width, int height, int bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask);

DLL_API BOOL DLL_CALLCONV FreeImage_HasRGBMasks(FIBITMAP *dib);

#if defined(__cplusplus)
}
#endif

BOOL SwapRedBlue32(FIBITMAP* dib); //This is the function that I want to use

 

SwapRedBlue32 is the function that I want to use in my engine. Keep in mind I'm building FreeImage as a static library and linking it to my engine.

 

Anyway, if you are an experienced c++ programmer (not me) you would have figured out by now why I got the linking issue only with the SwapRedBlue32 function. It's because it's not inside the extern "C" block.

 

so after doing the following, everything worked just fine.


//FreeImage.h
#define DLL_CALLCONV __stdcall
#define DLL_API __declspec(dllexport)

//----------------------------------------

//Utilities.h
#if defined(__cplusplus)
extern "C" {
#endif

DLL_API FIBITMAP * DLL_CALLCONV FreeImage_AllocateHeaderT(BOOL header_only, FREE_IMAGE_TYPE type, int width, int height, int bpp FI_DEFAULT(8), unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0));

DLL_API FIBITMAP * DLL_CALLCONV FreeImage_AllocateHeader(BOOL header_only, int width, int height, int bpp, unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0));

DLL_API FIBITMAP * DLL_CALLCONV FreeImage_AllocateHeaderForBits(BYTE *ext_bits, unsigned ext_pitch, FREE_IMAGE_TYPE type, int width, int height, int bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask);

DLL_API BOOL DLL_CALLCONV FreeImage_HasRGBMasks(FIBITMAP *dib);

DLL_API BOOL DLL_CALLCONV SwapRedBlue32(FIBITMAP* dib);

#if defined(__cplusplus)
}
#endif

 

I still don't know why this wasn't an issue before including the Windows.h header file. You would think that this linking problem would be a problem without having to include Windows.h.

 

I would love someone to explain this to me. Why does including Windows.h causes this issue and why this fix worked.

This topic is closed to new replies.

Advertisement