Sign in to follow this  
StoneMask

Linking error? Unesolved external symbols

Recommended Posts

StoneMask    293
I put together a program from my book with syntactically identical code, and it's giving me issues that imply I don't have a certain library linked or something? At least, this is what the other thread I saw told me. But I have everything linked correctly, I believe? So I need some help, because it's not compiling my other DirectX programs either anymore for some reason.

I'll organize this post so this thread isn't cluttered and unattractive. I know some topics get dropped just because people don't format their code in a way that's easy to look through.

Also, I am using a 32-bit Windows 7 machine. [url="http://i.imgur.com/ph8UF.png"]These are my specs[/url]. I am using [b]Microsoft Visual Studio 2010[/b] as my IDE.

[u][b]The problem[/b][/u]:
[spoiler]
When I compile my code, I get these errors:

1>dxgraphics.obj : error LNK2019: unresolved external symbol _Direct3DCreate9@4 referenced in function "int __cdecl Init_Direct3D(struct HWND__ *,int,int,int)" (?Init_Direct3D@@YAHPAUHWND__@@HHH@Z)

1>dxgraphics.obj : error LNK2019: unresolved external symbol _D3DXLoadSurfaceFromFileA@32 referenced in function "struct IDirect3DSurface9 * __cdecl LoadSurface(char *,unsigned long)" (?LoadSurface@@YAPAUIDirect3DSurface9@@PADK@Z)

1>dxgraphics.obj : error LNK2019: unresolved external symbol _D3DXGetImageInfoFromFileA@8 referenced in function "struct IDirect3DSurface9 * __cdecl LoadSurface(char *,unsigned long)" (?LoadSurface@@YAPAUIDirect3DSurface9@@PADK@Z)

1>dxgraphics.obj : error LNK2019: unresolved external symbol _D3DXCreateTextureFromFileExA@56 referenced in function "struct IDirect3DTexture9 * __cdecl LoadTexture(char *,unsigned long)" (?LoadTexture@@YAPAUIDirect3DTexture9@@PADK@Z)

1>game.obj : error LNK2019: unresolved external symbol _D3DXCreateSprite@8 referenced in function "int __cdecl Game_Init(struct
HWND__ *)" (?Game_Init@@YAHPAUHWND__@@@Z)
[/spoiler]

[u][b]Steps I took to solve it[/b][/u]:
[spoiler]I already knew I had to include d3d9.lib and d3dx9.lib, and I have added them, like so.
[img]http://i.imgur.com/VLDc3.png[/img]

And I also have the [b]Lib[/b] and [b]Include [/b]folders included in my [b]Include Directories[/b], as well as the [b]x64 [/b]folder in my [b]Library Directories[/b].
[img]http://i.imgur.com/b59U5.png[/img]

My version of the DirectX SDK is [b]Microsoft DirectX SDK (June 2010)[/b]. I changed the name of the folder to [b]Microsoft DirectX SDK June 2010[/b], but it still behaves the same way either way it's named. I've tried reinstalling SDKs of earlier and more recent versions and rebooting, but it still refuses to work.
[/spoiler]

[u][b]My code[/b][/u]:
[spoiler]
The file that the errors keep referencing is my dxgraphics.cpp, so I'll put that first.

[u][b]dxgraphics.h[/b][/u]
[spoiler][code]#ifndef DXGRAPHICS_H
#define DXGRAPHICS_H

//function prototypes
int Init_Direct3D(HWND, int, int, int);
LPDIRECT3DSURFACE9 LoadSurface(char *, D3DCOLOR);
LPDIRECT3DTEXTURE9 LoadTexture(char *, D3DCOLOR);

//variable declarations
extern LPDIRECT3D9 d3d;
extern LPDIRECT3DDEVICE9 d3ddev;
extern LPDIRECT3DSURFACE9 backbuffer;

#endif[/code][/spoiler]

[u][b]dxgraphics.cpp[/b][/u]
[spoiler][code]// dxgraphics.cpp; Direct3D framework source file

#include
#include
#include "dxgraphics.h"

// variable declaration
LPDIRECT3D9 d3d = NULL;
LPDIRECT3DDEVICE9 d3ddev = NULL;
LPDIRECT3DSURFACE9 backbuffer = NULL;


int Init_Direct3D(HWND hwnd, int width, int height, int fullscreen)
{
// initialize Direct3D
d3d = Direct3DCreate9(D3D_SDK_VERSION);
if (d3d == NULL)
{
MessageBox(hwnd, "Error initializing Direct3D", "Initialization Error", MB_OK);
return 0;
}

// set Direct3D presentation parameters
D3DPRESENT_PARAMETERS d3dParam;
ZeroMemory(&d3dParam, sizeof(d3dParam));

d3dParam.AutoDepthStencilFormat = D3DFMT_D16;
d3dParam.BackBufferCount = 1;
d3dParam.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dParam.BackBufferHeight = height;
d3dParam.BackBufferWidth = width;
d3dParam.EnableAutoDepthStencil = true;
d3dParam.hDeviceWindow = hwnd;
d3dParam.SwapEffect = D3DSWAPEFFECT_COPY;
d3dParam.Windowed = (!fullscreen);
d3dParam.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

// create Direct3D device
d3d->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dParam,
&d3ddev);

if (d3ddev == NULL)
{
MessageBox(hwnd, "Error creating Direct3D device", "Error", MB_OK);
return 0;
}

// clear the backbuffer to black
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

// create pointer to the back buffer
d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);

return 1;
}

LPDIRECT3DSURFACE9 LoadSurface(char *filename, D3DCOLOR transcolor)
{
LPDIRECT3DSURFACE9 image = NULL;
D3DXIMAGE_INFO info;
HRESULT result;

// get width and height from bitmap file
result = D3DXGetImageInfoFromFile(filename, &info);
if (result != D3D_OK)
return NULL;

// create surface
result = d3ddev->CreateOffscreenPlainSurface(
info.Width,
info.Height,
D3DFMT_X8R8G8B8,
D3DPOOL_DEFAULT,
&image,
NULL);

if (result != D3D_OK)
return NULL;

// load surface from file into newly created surface
result = D3DXLoadSurfaceFromFile(
image,
NULL,
NULL,
filename,
NULL,
D3DX_DEFAULT,
transcolor,
NULL);

// make sure the file was loaded alright
if (result != D3D_OK)
return NULL;

return image;
}

LPDIRECT3DTEXTURE9 LoadTexture(char *filename, D3DCOLOR transcolor)
{
// the texture pointer
LPDIRECT3DTEXTURE9 texture = NULL;

// the struct for reading bitmap file info
D3DXIMAGE_INFO info;

// standard Windows return value
HRESULT result;

// get width and height from bitmap file
result = D3DXGetImageInfoFromFile(filename, &info);
if (result != D3D_OK)
return NULL;

// create the new texture b loading a bitmap image file
D3DXCreateTextureFromFileEx(
d3ddev,
filename,
info.Width,
info.Height,
1,
D3DPOOL_DEFAULT,
D3DFMT_UNKNOWN,
D3DPOOL_DEFAULT,
D3DX_DEFAULT,
D3DX_DEFAULT,
transcolor,
&info,
NULL,
&texture);

// make sure the bitmap texture was loaded correctly
if (result != D3D_OK)
return NULL;

return texture;
}[/code][/spoiler]

[u][b]game.h[/b][/u]
[spoiler][code]#ifndef GAME_H
#define GAME_H

#include
#include
#include
#include
#include
#include
#include "dxgraphics.h"

// application title
#define APPTITLE "directX Practice"

// screen setup
#define FULLSCREEN 1 // 0 = windowed, 1 = fullscreen
#define SCREEN_WIDTH 1366
#define SCREEN_HEIGHT 768

// macros to read the keyboard asynchronously
#define KEY_DN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)

// function prototypes
int Game_Init(HWND);
void Game_Run(HWND);
void Game_End(HWND);

// sprite structure
typedef struct {
int width, height;
int curFrame, lastFrame;
int frameDelay, frameCount;

int x_Pos, y_Pos;
int x_Speed, y_Speed;
} SPRITE;

#endif[/code][/spoiler]

[u][b]game.cpp[/b][/u]
[spoiler][code]#include "game.h"

LPD3DXSPRITE sprite_handler;
LPDIRECT3DSURFACE9 background;
LPDIRECT3DTEXTURE9 spr_Mufn;
SPRITE Mufn;

HRESULT result;

// timing variable
long start = GetTickCount();

// initializes the game
int Game_Init(HWND hwnd)
{
char s[20];

// random number seed
srand(time(NULL));

// create spriter handler object
result = D3DXCreateSprite(d3ddev, &sprite_handler);
if (result != D3D_OK)
return 0;

// load the sprite animation
spr_Mufn = LoadTexture(s, D3DCOLOR_XRGB(255, 0, 255));
if (spr_Mufn == NULL)
return 0;

// load the background image
background = LoadSurface("background.bmp", NULL);

// initialize the sprite's properties
Mufn.width = 16;
Mufn.height = 16;
Mufn.curFrame = 0;
Mufn.lastFrame = 1;
Mufn.frameDelay = 2;
Mufn.frameCount = 0;
Mufn.x_Pos = 100;
Mufn.y_Pos = 96;
Mufn.x_Speed = 4;
Mufn.y_Speed = 0;

return 1;
}

// the main game loop
void Game_Run(HWND hwnd)
{
// make sure the Direct3D Device is valid
if (d3ddev == NULL)
return;

// keep frame rate steady
if (GetTickCount() - start >= 30)
{
// reset timing
start = GetTickCount();

// move the sprite
Mufn.x_Pos += Mufn.x_Speed;
Mufn.y_Pos += Mufn.y_Speed;

// screen wrap
if (Mufn.x_Pos > SCREEN_WIDTH)
Mufn.x_Pos = -Mufn.width;
if (Mufn.x_Pos < -Mufn.width)
Mufn.x_Pos = SCREEN_WIDTH + Mufn.width;
if (Mufn.y_Pos > SCREEN_HEIGHT + Mufn.height)
Mufn.y_Pos = 0;
if (Mufn.y_Pos < -Mufn.height)
Mufn.x_Pos = -Mufn.height;

// does the animation need to loop?
if (++Mufn.frameCount > Mufn.frameDelay)
{
// reset counter
Mufn.frameCount = 0;

// animate the sprite
if (++Mufn.curFrame > Mufn.lastFrame)
Mufn.curFrame = 0;
}
}

// start rendering
if (d3ddev->BeginScene())
{
// erase the entire background
d3ddev->StretchRect(background, NULL, backbuffer, NULL, D3DTEXF_NONE);

// start sprite handler
sprite_handler->Begin(D3DXSPRITE_ALPHABLEND);

// create vector to update sprite position
D3DXVECTOR3 position((float)Mufn.x_Pos, (float)Mufn.y_Pos, 0);

// configure the rect for the source file
RECT srcRect;
int columns = 8;
srcRect.left = (Mufn.curFrame % columns) * Mufn.width;
srcRect.top = (Mufn.curFrame / columns) * Mufn.height;
srcRect.right = srcRect.left + Mufn.width;
srcRect.bottom = srcRect.top + Mufn.height;

// draw the sprite
sprite_handler->Draw(
spr_Mufn,
&srcRect,
NULL,
&position,
D3DCOLOR_XRGB(255, 255, 255));

// stop drawing
sprite_handler->End();

// stop rendering
d3ddev->EndScene();
}

// display the backbuffer onto the screen
d3ddev->Present(NULL, NULL, NULL, NULL);

// check for escape key to exit the program
if (KEY_DN(VK_ESCAPE))
PostMessage(hwnd, WM_DESTROY, 0, 0);
}

// frees memory and cleans up
void Game_End(HWND hwnd)
{
if (spr_Mufn != NULL)
spr_Mufn->Release();

if (background != NULL)
background->Release();

if (sprite_handler != NULL)
sprite_handler->Release();
}[/code][/spoiler]

[u][b]winmain.cpp[/b][/u]
[spoiler][code]// DirectX Practice and Study
// Winmain.cpp

#include
#include
#include
#include
#include "dxgraphics.h"
#include "game.h"

// window event callback function
LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
// release the Direct3D
if (d3ddev != NULL)
d3ddev->Release();

// release the Direct3D object
if (d3d != NULL)
d3d->Release();

// call the front-end shutdown function
Game_End(hWnd);

// tell Windows to kill the program
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}

// helper function to set up the window properties
ATOM MyRegisterClass(HINSTANCE hInstance)
{
// create the window class structure
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);

// fill the struct with info
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = NULL;
wc.hIconSm = NULL;
wc.hInstance = hInstance;
wc.lpfnWndProc = (WNDPROC)WinProc;
wc.lpszClassName = APPTITLE;
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;

// set up the window with the class info
return RegisterClassEx(&wc);
}

// entry point for a Windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
HWND hWnd;

// register the class
MyRegisterClass(hInstance);

// set up the screen in windowed or fullscreen mode
DWORD style;
if (FULLSCREEN)
style = WS_EX_TOPMOST | WS_VISIBLE | WS_POPUP;
else
style = WS_OVERLAPPED;

// create a new window
hWnd = CreateWindow(
APPTITLE,
APPTITLE,
style,
CW_USEDEFAULT,
CW_USEDEFAULT,
SCREEN_WIDTH,
SCREEN_HEIGHT,
NULL,
NULL,
hInstance,
NULL);

// was there an error?
if (!hWnd)
return false;

// display the window
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

if (!Init_Direct3D(hWnd, SCREEN_WIDTH, SCREEN_HEIGHT, FULLSCREEN))
return 0;

// initialize the game
if (!Game_Init(hWnd))
{
MessageBox(hWnd, "Error initializing the game", "Initialization error", MB_OK);
return 0;
}

// main message loop
short done = 0;
while(!done)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// look for quit message
if (msg.message == WM_QUIT)
done = 1;

// decode and pass messages on to WinProc
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
// process game loop
Game_Run(hWnd);
}
return msg.wParam;
}[/code][/spoiler]
[/spoiler]

I hope you guys can help me with this problem! I honestly can't really advance much without solving this first.
Thanks!

Share this post


Link to post
Share on other sites
Cornstalks    7030
First, +1 for the nice post and showing the problem, what you did to try to fix it, and your code. So good to see.

Anyway, this may or may not solve your problem, but you said you have a 32-bit Windows 7 machine, but you're trying to use the 64-bit libraries (in the x64 folder). The libs in the x86 folder are for 32-bit machines like yours. Try changing your lib directory from the x64 folder to the x86 folder.

Share this post


Link to post
Share on other sites
StoneMask    293
Oh. I thought the x64 was for the 32-bit machines, lol. And yeah, I was really fed up with vague questions with vaguer answers in my Google results, so I'd rather keep my problem nice and clear so there isn't a back-and-forth of "did you do this?" "yes" I want my problem solved as soon as possible, and clear, concise explanations are the best way to get that.

The program works now! Thanks for throwing my hours of trouble out the window.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this