Advertisement

Wierd unresolved externals...

Started by March 13, 2003 10:46 AM
7 comments, last by Arkainium 21 years, 8 months ago
I wrote a utility library to do various things like bitmap loading, making colors, filling surfaces, etc. Anyway, the library builds fine, and I''ve set the directories in my MSVC settings. However, now I''m trying to use the library in my project. So, I include the header and link in the library. Everything in the library that doesn''t access directx structures links in successfully. For example, the function that fills the surface takes a DirectDraw surface, so I get a wierd unresolved external error. I can''t understand this.. the library built successfully, and all the directx in my main project is linked in. The only thing that doesn''t link are the functions in my library that make use of directx structures. Again, I can''t comprehend this because classes and other functions in my library DO link. I''ve been stuck on this for a while. So, please, if you have any advice that will enlighten me, please share it. Thanks.
you still need to link with appropriate dx libraries when you''re building your application. building a library doesn''t link it to anything.
Advertisement
quote: Original post by niyaw
you still need to link with appropriate dx libraries when you''re building your application. building a library doesn''t link it to anything.



Aye, I know. That''s what so wierd...
why? a library is just a collection of object files. no linking is performed when you build a library. if you''re looking for something really standalone, a dll might be the answer. or you can use #pragma comment to embed references to libraries into the object files so that you don''t have to specify them for every project.
Well, I made a static library in MSVC, so when I build, I get a .lib as my output.

This is the header and the source that make up my library...

The header:

  #ifndef DDRAWUSEFUL_H#define DDRAWUSEFUL_H#include <windows.h>#include <ddraw.h>#include <fstream>namespace DDrawUseful{	const int BITMAP_ID = 0x4D42;	class BitmapFile	{	public:		// constructor		BitmapFile(const char *fileName = NULL);		// copy constructor		BitmapFile(const BitmapFile& bitmap);				// destructor		~BitmapFile();				// assignment operator		void operator =(const BitmapFile& bitmap);		// loads the specified filename		bool Load(const char *fileName);		// flips an inverted bitmap		bool Flip();		// accessors		unsigned char *GetBuffer()	{ return buffer; }		PALETTEENTRY *GetPalette()	{ return palette; }		BITMAPINFOHEADER &GetInfoHeader()	{ return infoHeader; }				BITMAPFILEHEADER &GetFileHeader()	{ return fileHeader; }	private:		BITMAPFILEHEADER	fileHeader;		// file's properties		BITMAPINFOHEADER	infoHeader;		// bitmap's properties		PALETTEENTRY		palette[256];	// palette if 8-bit bitmap		unsigned char		*buffer;		// pointer to pixel data	};	template <class T>	inline void DX_InitStruct(T &data);	inline int MakeColor16(int r, int g, int b);	inline int MakeColor24(int r, int g, int b);	inline int MakeColor32(int r, int g, int b, int a = 0);	inline void FillSurface(LPDIRECTDRAWSURFACE7 lpDDS, int color);}#endif  


The source:

  #include "DDrawUseful.h"namespace DDrawUseful{	using namespace std;	// constructor	BitmapFile::BitmapFile(const char *fileName)	{		buffer = NULL;		memset(&fileHeader, 0, sizeof(BITMAPFILEHEADER));		memset(&infoHeader, 0, sizeof(BITMAPINFOHEADER));		memset(palette, 0, sizeof(PALETTEENTRY)*256);		Load(fileName);	}	// copy constructor	BitmapFile::BitmapFile(const BitmapFile& bitmap)	{	}		// destructor	BitmapFile::~BitmapFile()	{		if ( buffer != NULL )		{			delete [] buffer;			buffer = NULL;		}	}		// assignment operator	void BitmapFile::operator =(const BitmapFile& bitmap)	{	}	// loads the specified filename	bool BitmapFile::Load(const char *fileName)	{		if ( fileName == NULL )		{			return false;		}		ifstream ins(fileName);		// make sure the file opened successfully		if ( ins.fail() )		{			return false;		}		// now load the bitmap file header		ins.read((char *)&fileHeader, sizeof(BITMAPFILEHEADER));		// test if this is a bitmap file		if ( fileHeader.bfType != BITMAP_ID )		{			ins.close();			return false;		}		// now we know this is a bitmap		// read the bitmap info header		ins.read((char *)&infoHeader, sizeof(BITMAPINFOHEADER));		// now load the color palette if it is an 8-bit bitmap		if ( infoHeader.biBitCount == 8 )		{			ins.read((char *)palette, sizeof(PALETTEENTRY)*256);			// now set all the flags in the palette correctly			// and fix the reversed BGR RGBQUAD data format			for ( int index = 0; index < 256; index++ )			{				// swap red and blue fields				int tempColor = palette[index].peRed;				palette[index].peRed = palette[index].peBlue;				palette[index].peBlue = tempColor;				palette[index].peFlags = PC_NOCOLLAPSE;			}		}		// set the position of the pointer in the file to the		// beginning of the image data itself		ins.seekg(-(int)infoHeader.biSizeImage, ios_base::end);		// now read in the image data		if ( infoHeader.biBitCount == 8  ||			 infoHeader.biBitCount == 16 ||			 infoHeader.biBitCount == 24 )		{			// delete the last image if there was one			if ( buffer != NULL )			{				delete [] buffer;				buffer = NULL;			}			// allocate the memory for the image			buffer = new unsigned char[infoHeader.biSizeImage];			// make sure memory was allocated			if ( buffer == NULL )			{				ins.close();				return false;			}			// now read the image data into buffer			ins.read((char *)buffer, infoHeader.biSizeImage);		}		else		{			ins.close();			return false;		}		// we're done reading the file		ins.close();		// flip the bitmap in case it's inverted		Flip();		return true;	}	bool BitmapFile::Flip()	{		// used to perform the image processing		unsigned char *temp = NULL;		// pitch of bitmap		int bytesPerLine = infoHeader.biWidth*(infoHeader.biBitCount/8);				// allocate the temporary buffer		temp = new unsigned char[bytesPerLine*infoHeader.biHeight];				// make sure memory was allocated		if ( temp == NULL )		{			return false;		}				// copy image to work area		memcpy(temp, buffer, bytesPerLine*infoHeader.biHeight);		// flip vertically		for ( int index = 0; index < infoHeader.biHeight; index++ )		{			memcpy(&buffer[((infoHeader.biHeight-1) - index)*bytesPerLine],				&temp[index*bytesPerLine], bytesPerLine);		}				// release the memory		delete [] temp;		return true;	}	template <class T>	void DX_InitStruct(T &data)	{		memset(&data, 0, sizeof(data));		data.dwSize = sizeof(data);	}	int MakeColor16(int r, int g, int b)	{		int color;		color = ( ( (b%32)		 ) +				  ( (g%64) << 5	 ) +				  ( (r%32) << 11 ) );		return color;	}	int MakeColor24(int r, int g, int b)	{		int color;		color = ( ( (b%256)       ) +				  ( (g%256) << 8  ) +				  ( (r%256) << 16 ) );		return color;	}	int MakeColor32(int r, int g, int b, int a)	{		int color;		color = ( ( (b%256)       ) +				  ( (g%256) << 8  ) +				  ( (r%256) << 16 ) +				  ( (a%256) << 24 ) );		return color;	}	void FillSurface(LPDIRECTDRAWSURFACE7 lpDDS, int color)	{		DDBLTFX ddBltFX;				// clear out the structure and set the size field		DX_InitStruct(ddBltFX);				// set the fill color field to the desired color		ddBltFX.dwFillColor = color;		// ready to blt to surface		lpDDS->Blt(	NULL,// ptr to dest rectangle					NULL,// ptr to source surface, NA					NULL,// ptr to source rectangle, NA					DDBLT_COLORFILL | DDBLT_WAIT,// fill and wait					&ddBltFX );// ptr to DDBLTFX structure	}}  



When I use this lib in a project, everything links except for the functions that reference directx structures.

Here are the linker errors:

Linking...
main.obj : error LNK2001: unresolved external symbol "void __cdecl DDrawUseful::FillSurface(struct IDirectDrawSurface7 *,int)" (?FillSurface@DDrawUseful@@YAXPAUIDirectDrawSurface7@@H@Z)
main.obj : error LNK2001: unresolved external symbol "void __cdecl DDrawUseful::DX_InitStruct(struct _DDSURFACEDESC2 &)" (?DX_InitStruct@DDrawUseful@@YAXAAU_DDSURFACEDESC2@@@Z)
Debug/bitmaploading.exe : fatal error LNK1120: 2 unresolved externals
Error executing link.exe.

[edited by - Arkainium on March 13, 2003 1:35:37 PM]
the only interpretation of your post i can come up with is that you''re confusing import libraries with collection-of-object-files libraries. import libraries don''t have any code in them, but the dlls that they provide access to may have dependencies on other dlls. collection-of-object-files libraries are just that, a bunch of object files. they have dependencies on other object files and import libraries.
Advertisement
great, now it turns out i''ve been trying to troubleshoot the wrong problem. an excerpt from my soon-to-be-available "smart questions, gamedev edition" page:

What I am thinking when people post certain things



Q: I''m doing X, and I''m getting some compiler errors about something.


If you can''t be bothered to list the exact errors you''re getting, I can''t be bothered to help you.
The last thing I want to do is stay over your shoulder trying to understand what it is you''re having a problem
with. Let someone who hasn''t been here for as long as I have, and who isn''t yet tired of asking for
more information and/or guessing the problem, reply, while I move on.


inline functions must be defined before you use them. you can't have definition of an inline function in one source file, declaration in another, and use it from the third source file. put all inline code in headers or don't use inline.

same thing with templates.

[edited by - niyaw on March 13, 2003 1:43:52 PM]
quote: If you can't be bothered to list the exact errors you're getting, I can't be bothered to help you.
The last thing I want to do is stay over your shoulder trying to understand what it is you're having a problem
with. Let someone who hasn't been here for as long as I have, and who isn't yet tired of asking for
more information and/or guessing the problem, reply, while I move on.

Take it easy... I'm sorry about not posting the exact error and source earlier, I was at school then.

I got it to work, btw. Thanks.


[edited by - Arkainium on March 13, 2003 1:56:38 PM]

This topic is closed to new replies.

Advertisement