Sign in to follow this  
PedroMachin

Linker Nightmares

Recommended Posts

Hello there, this is my first post here in GameInstitute, please be kind to my ignorace :)

I am running on Visual C++ Express with the June 2010 release of DirectX.

[b]My problem:[/b]
[b]This declaration: [/b]
const DIDATAFORMAT& pointerDataFormatAlias = c_dfDIMouse;
[b]Is causing the following Linker error:[/b]
1>eiInput.obj : error LNK2001: unresolved external symbol _c_dfDIMouse

[b]I have included <dinput.h> in the file as well as added it to my header files and included it in my project.[/b]

[b]I have added the following paths to the libraries under "Configuration Properties/VC++ Directories/Library Directories"[/b]
C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x64
C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x86
C:\Program Files %28x86%29\Microsoft SDKs\Windows\v7.0A\Lib

[b]I have added the following paths to the include directories under "Configuration Properties/VC++ Directories/Library Directories"[/b]
C:\Program Files %28x86%29\Microsoft SDKs\Windows\v7.0A\Include
C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include
C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86

[b]I have added the relevant library directories under "Linker/General":[/b]
C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;C:\Program Files %28x86%29\Microsoft SDKs\Windows\v7.0A\Lib;%(AdditionalLibraryDirectories)

[b]I have added the relevant (as far as I know) libraries themselves under Linker/Input:[/b]
dinput8.lib;dxguid.lib;kernel32.lib;user32.lib;gdi32.lib;comdlg32.lib;ole32.lib;winmm.lib;psapi.lib;d3d9.lib;%(AdditionalDependencies)



[b]Just in case, I'm missing something important, this is the whole Command Line under "Linker" showing all the included libraries:[/b]

/OUT:"C:\Users\Pedro\Documents\Visual Studio 2010\Projects\DirectInputScroll\Debug\DirectInputScroll.exe" /INCREMENTAL /NOLOGO /LIBPATH:"C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x64" /LIBPATH:"C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x86" /LIBPATH:"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Lib" "dinput8.lib" "dxguid.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "comdlg32.lib" "ole32.lib" "winmm.lib" "psapi.lib" "d3d9.lib" "winspool.lib" "advapi32.lib" "shell32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /MANIFEST /ManifestFile:"Debug\DirectInputScroll.exe.intermediate.manifest" /ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"C:\Users\Pedro\Documents\Visual Studio 2010\Projects\DirectInputScroll\Debug\DirectInputScroll.pdb" /SUBSYSTEM:WINDOWS /PGD:"C:\Users\Pedro\Documents\Visual Studio 2010\Projects\DirectInputScroll\Debug\DirectInputScroll.pgd" /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:QUEUE
[i]
[b]What the heck is going on?[/b][/i]

Share this post


Link to post
Share on other sites
Hidden
[quote name='mhagain' timestamp='1318843765' post='4873389']
You need to #define DIRECTINPUT_VERSION as 0x0700 or greater before your #include of dinput.h, otherwise this macro won't be available. Did you not get a "DIRECTINPUT_VERSION not defined" warning when you compiled?
[/quote]

Thank You, now things are starting to make sense....

However, when I #define DIRECTINPUT_VERSION as 0x0700, I realized that my program is actually using structures under the #if(DIRECTINPUT_VERSION >= 0x0800), such as the IDirectInputDevice8 struct.
So, if I define version 0x0700, I get rid of the linker errors, but then I get a ton of compile errors.

It seems that I need to define #define DIRECTINPUT_VERSION as 0x0800 given all the version 8 structures (the version is defined automatically by dinput.h if there is no explicit version define, so I'm back to where I started). However, it seems that for some reason, "extern const DIDATAFORMAT c_dfDIMouse;" in the dinput.h file is not being linked to whichever external file it was defined!

Share this post


Link to post
[quote name='pmachin' timestamp='1318865654' post='4873484']
[quote name='mhagain' timestamp='1318843765' post='4873389']
You need to #define DIRECTINPUT_VERSION as 0x0700 or greater before your #include of dinput.h, otherwise this macro won't be available. Did you not get a "DIRECTINPUT_VERSION not defined" warning when you compiled?
[/quote]

Thank You, now things are starting to make sense....

However, when I #define DIRECTINPUT_VERSION as 0x0700, I realized that my program is actually using structures under the #if(DIRECTINPUT_VERSION >= 0x0800), such as the IDirectInputDevice8 struct.
So, if I define version 0x0700, I get rid of the linker errors, but then I get a ton of compile errors.

It seems that I need to define #define DIRECTINPUT_VERSION as 0x0800 given all the version 8 structures (or not define it at all since the version is defined automatically by dinput.h if there is no explicit version define, which apparently was what was going on before).

Apparently, the problem is that "extern const DIDATAFORMAT c_dfDIMouse;" in the dinput.h file is not being linked to whichever external file it was defined! Like I showed in my original post in the linker command line, dxguid.lib is included in the linker.
[/quote]

I attached the whole project, just in case someone wants to take a gander...

Share this post


Link to post
Share on other sites
[quote name='The King2' timestamp='1318829473' post='4873328']
Try linking to dinput.lib too. Just a suggestion I found after searching in google for 2 min ;)
[/quote]

Thanks King, but dinput.lib does not exist, only dinput8.lib. Thanks for the suggestion :)

Share this post


Link to post
Share on other sites
Go to your projects property page and, in the [b]Additional Library Directories[/b] list, move [b]C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86[/b] above [b]C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64[/b].

EDIT:
I should explain that a bit better. Your project is set to target 32bit but the linker is finding the 64bit libraries, since they're first in the list.

Share this post


Link to post
Share on other sites
[quote name='AverageMidget' timestamp='1318872949' post='4873546']
Go to your projects property page and, in the [b]Additional Library Directories[/b] list, move [b]C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86[/b] above [b]C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64[/b].

EDIT:
I should explain that a bit better. Your project is set to target 32bit but the linker is finding the 64bit libraries, since they're first in the list.
[/quote]

Stupid Linker!
Thanks AverageMidget. You guys are awesome!

Share this post


Link to post
Share on other sites
I moved on to another project, and are running into Linker problems again! Again, I[color="#1C2837"][size="2"] am running on Visual C++ Express with the June 2010 release of DirectX. [/size][/color]

All the libraries added are listed below the output below:

[b]This time I get:[/b]
1>------ Build started: Project: Circle, Configuration: Release Win32 ------
1>Circle.obj : error LNK2001: unresolved external symbol "public: long __thiscall CD3DFont::InitDeviceObjects(struct IDirect3DDevice9 *)" (?InitDeviceObjects@CD3DFont@@QAEJPAUIDirect3DDevice9@@@Z)
1>Circle.obj : error LNK2001: unresolved external symbol "void __cdecl D3DUtil_InitLight(struct _D3DLIGHT9 &,enum _D3DLIGHTTYPE,float,float,float)" (?D3DUtil_InitLight@@YAXAAU_D3DLIGHT9@@W4_D3DLIGHTTYPE@@MMM@Z)
1>D3DApplication.obj : error LNK2001: unresolved external symbol "public: long __thiscall CD3DMesh::Create(struct IDirect3DDevice9 *,char *)" (?Create@CD3DMesh@@QAEJPAUIDirect3DDevice9@@PAD@Z)
1>D3DApplication.obj : error LNK2001: unresolved external symbol "public: long __thiscall CD3DFrame::Render(struct IDirect3DDevice9 *,int,int)" (?Render@CD3DFrame@@QAEJPAUIDirect3DDevice9@@HH@Z)
1>D3DApplication.obj : error LNK2001: unresolved external symbol "public: long __thiscall CD3DFrame::RestoreDeviceObjects(struct IDirect3DDevice9 *)" (?RestoreDeviceObjects@CD3DFrame@@QAEJPAUIDirect3DDevice9@@@Z)
1>D3DApplication.obj : error LNK2001: unresolved external symbol "long __cdecl D3DUtil_SetDeviceCursor(struct IDirect3DDevice9 *,struct HICON__ *)" (?D3DUtil_SetDeviceCursor@@YAJPAUIDirect3DDevice9@@PAUHICON__@@@Z)
1>eisdk.lib(d3dfile.obj) : error LNK2001: unresolved external symbol _D3DXLoadMeshFromX@28
1>eisdk.lib(d3dfile.obj) : error LNK2001: unresolved external symbol _D3DXLoadMeshFromXof@28
1>eisdk.lib(d3dfile.obj) : error LNK2001: unresolved external symbol _D3DXComputeNormals@4
1>C:\Users\Pedro\Documents\Visual Studio 2010\Projects\Circle\Release\Circle.exe : fatal error LNK1120: 9 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

[b]Character set is Multibyte since I'm compiling older code[/b]
[b]
I changed the RunTime Library to /MT (Multithreaded) and are running a Release build[/b]

[b]These are the classes under Linker/Input/Additional Dependencies:[/b]
libcmt.lib
dinput8.lib
d3d9.lib
dxguid.lib
kernel32.lib
user32.lib
gdi32.lib
comdlg32.lib
ole32.lib
winmm.lib
psapi.lib

[b]These are the classes under Linker/Input/Ignore:[/b]
libc.lib
msvcrt.lib
libcd.lib
libcp.lib
libcmtd.lib
msvcrtd.lib

[b]Under Linker/General/ Additional Library Directories:[/b]
C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86
C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64
C:\Program Files %28x86%29\Microsoft SDKs\Windows\v7.0A\Lib

[b]Under VC++ Directories:[/b]
[b]Include:[/b]
C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include
C:\Program Files %28x86%29\Microsoft SDKs\Windows\v7.0A\Include
[b]Library Directories:[/b]
C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86
C:\Program Files %28x86%29\Microsoft SDKs\Windows\v7.0A\Include


Thanks!

Share this post


Link to post
Share on other sites
I'll try and help in a way that'll help you figure these things out for yourself.

If you look at the [url="http://msdn.microsoft.com/en-us/library/windows/desktop/bb172890(v=vs.85).aspx"]msdn entry[/url] for D3DXLoadMeshFromX function (which is one of your linker errors) and you scroll down, you'll see the requirments. The library is [b]D3dx9.lib[/b]


Is that lib included in your dependencies list?

EDIT:
I'll add that [b]unresolved external symbol[/b] basically means it can't find the proper signature of the following function(s), so you have to tell the linker where to find it. In case you were confused by that part.

Share this post


Link to post
Share on other sites
[quote name='AverageMidget' timestamp='1319332978' post='4875494']
I'll try and help in a way that'll help you figure these things out for yourself.

If you look at the [url="http://msdn.microsoft.com/en-us/library/windows/desktop/bb172890(v=vs.85).aspx"]msdn entry[/url] for D3DXLoadMeshFromX function (which is one of your linker errors) and you scroll down, you'll see the requirments. The library is [b]D3dx9.lib[/b]


Is that lib included in your dependencies list?

EDIT:
I'll add that [b]unresolved external symbol[/b] basically means it can't find the proper signature of the following function(s), so you have to tell the linker where to find it. In case you were confused by that part.
[/quote]


AverageMidget, I want to be able to figure these things out for myself and as such I appreciate the fact that you give explanations as opposed to just giving an answer.

Ok, so in the case of D3DXLoadMeshFromX function, the closest that I could find to that function in the project code was the LoadMesh function in d3dfile.h
I added d3dx9.lib to the linker requirements to no avail. Now, the msdn entry that you referenced says that d3dx9Mesh.h is also a requirement. I downloaded this header file from Koders.com, added it to the header's directory and #included it in the file where I'm actually loading the mesh file (However, the call that I'm making is: bool D3DModel::Load(LPCTSTR xFileName, LPDIRECT3DDEVICE9 dev) so I'm a bit confused how the D3DXLoadMeshFromX function is being called). What am I doing wrong?

From reading some other posts it seems that sometimes you have to also add external .cpp files to the project such as d3dapp.cpp (not just headers and libraries), could that be the case here?
In particular I read: [url="http://www.gamedev.net/topic/227090-problem-building-a-dx-sample/"]http://www.gamedev.n...ng-a-dx-sample/[/url] and tried importing the .cpp files suggested (d3dapp.cpp, d3dfont.cpp, d3denumeration.cpp) however, those files were not in my sdk download and if I try downloading them from Koders.com, the files seem to be out of date as they are calling non-existing headers.

Thanks, and again excuse my noobishness.
[size="2"] [/size]

Share this post


Link to post
Share on other sites
[quote name='pmachin' timestamp='1319348995' post='4875537']...(However, the call that I'm making is: bool D3DModel::Load(LPCTSTR xFileName, LPDIRECT3DDEVICE9 dev) so I'm a bit confused how the D3DXLoadMeshFromX function is being called). What am I doing wrong?[/quote]

I would imagine that [b]D3DXLoadMeshFromX[/b] is being called from within the [b]D3DModel::Load[/b] method. I, however, am having a hard time finding that. It seems like that method (and most of the other methods listed in your linker errors) are from some DirectX SDK samples. Not actual documented Microsoft source.

[quote name='pmachin' timestamp='1319348995' post='4875537'][color="#1C2837"][size="2"]From reading some other posts it seems that sometimes you have to also add external .cpp files to the project such as d3dapp.cpp (not just headers and libraries), could that be the case here?[/size][/color][/quote]

That is sometimes the case. If the author of the code you're trying to use left it as a plain .cpp file (not compiled into a .dll or .lib), you would add that to your project and include the header, where you want to use the code.

In my poking around, I found the [b][color="#1C2837"][size="2"]CD3DMesh[/size][/color][/b][color="#1C2837"][size="2"] and [/size][/color][b][color="#1C2837"][size="2"]CD3DFrame[/size][/color][/b][color="#1C2837"][size="2"] classes defined in a file named [b]d3dfile.cpp[/b]. Also, these samples appear to be part of the DirectX 9 SDK samples.[/size][/color]

Share this post


Link to post
Share on other sites
Hidden
[quote name='AverageMidget' timestamp='1319357168' post='4875555']
[quote name='pmachin' timestamp='1319348995' post='4875537']...(However, the call that I'm making is: bool D3DModel::Load(LPCTSTR xFileName, LPDIRECT3DDEVICE9 dev) so I'm a bit confused how the D3DXLoadMeshFromX function is being called). What am I doing wrong?[/quote]

I would imagine that [b]D3DXLoadMeshFromX[/b] is being called from within the [b]D3DModel::Load[/b] method. I, however, am having a hard time finding that. It seems like that method (and most of the other methods listed in your linker errors) are from some DirectX SDK samples. Not actual documented Microsoft source.

[quote name='pmachin' timestamp='1319348995' post='4875537'][color="#1C2837"][size="2"]From reading some other posts it seems that sometimes you have to also add external .cpp files to the project such as d3dapp.cpp (not just headers and libraries), could that be the case here?[/size][/color][/quote]

That is sometimes the case. If the author of the code you're trying to use left it as a plain .cpp file (not compiled into a .dll or .lib), you would add that to your project and include the header, where you want to use the code.

In my poking around, I found the [b][color="#1C2837"][size="2"]CD3DMesh[/size][/color][/b][color="#1C2837"][size="2"] and [/size][/color][b][color="#1C2837"][size="2"]CD3DFrame[/size][/color][/b][color="#1C2837"][size="2"] classes defined in a file named [b]d3dfile.cpp[/b]. Also, these samples appear to be part of the DirectX 9 SDK samples.[/size][/color]
[/quote]

You we're right, most of the problem emerged due to d3dfile.cpp. Specifically, the lib included in my sample project not being recent. Instead, I had to download an old copy of d3dfile.cpp and update its structures. After it took me all day to do this, I saw that another person had posted the solution to this exact same problem in gamedev! Well, at least I learned something :) ([url="http://www.gamedev.net/topic/330646-using-older-samples-with-dx90c/"]http://www.gamedev.n...les-with-dx90c/[/url])

Now, I finally got the project to compile and link (at least in release mode) and I just get a black screen. I tracked down the problem to the GetAdapterCount() always returning zero and therefore not building a device list. I looked this up online, but I only found some reference to the OS sometimes being at fault in some systems?! Not sure where to go from here.


HRESULT D3DApplication::BuildDeviceList()
{
const DWORD dwNumDeviceTypes = 2;
const TCHAR* strDeviceDescs[] = { _T("HAL"), _T("REF") };
const D3DDEVTYPE DeviceTypes[] = { D3DDEVTYPE_HAL, D3DDEVTYPE_REF };

BOOL bHALExists = FALSE;
//BOOL bHALIsWindowedCompatible = FALSE;
BOOL bHALIsDesktopCompatible = FALSE;
BOOL bHALIsSampleCompatible = FALSE;

/* debug code
UINT adapterCount = m_pD3D->GetAdapterCount();
if(adapterCount == 0)
{
return 0; <<<<<-------always exists here
}else if(adapterCount == 1)
{
return 1;
}*/

// Loop through all the adapters on the system (usually, there's just one
// unless more than one graphics card is present).
for( UINT iAdapter = 0; iAdapter < m_pD3D->GetAdapterCount(); iAdapter++ )
{
// Fill in adapter info

.........

Share this post


Link to post

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