过去两天我一直在这上面,并且谷歌搜索尽可能多地解决这个错误。不幸的是,到目前为止我发现的一切似乎都没有解决问题。我已经三重检查我的包含保护,以及我的定义虚拟函数(它们都有),并且已经注释掉了我认为可能是该问题的贡献者的各种代码块。唉,我尝试过的任何事都没有帮助。同样的错误。
如果有人可以查看我的代码并指出我正确的方向,那将是一个巨大的帮助。
错误如下:
1>TriangleDemo.obj : error LNK2001: unresolved external symbol "public: virtual bool __thiscall stitch::PixelShader::CreateShader(void)" (?CreateShader@PixelShader@stitch@@UAE_NXZ)
1>FileUtility.obj : error LNK2001: unresolved external symbol "public: virtual bool __thiscall stitch::PixelShader::CreateShader(void)" (?CreateShader@PixelShader@stitch@@UAE_NXZ)
1>TriangleDemo.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall stitch::PixelShader::Recompile(void)" (?Recompile@PixelShader@stitch@@UAEXXZ)
1>FileUtility.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall stitch::PixelShader::Recompile(void)" (?Recompile@PixelShader@stitch@@UAEXXZ)
1>FileUtility.obj : error LNK2019: unresolved external symbol "public: __thiscall stitch::PixelShader::PixelShader(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::tr1::shared_ptr<struct RenderData> const &)" (??0PixelShader@stitch@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@000ABV?$shared_ptr@URenderData@@@tr1@3@@Z) referenced in function "public: static class stitch::PixelShader __cdecl stitch::FileUtility::LoadPixelShader(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::tr1::shared_ptr<struct RenderData> const &)" (?LoadPixelShader@FileUtility@stitch@@SA?AVPixelShader@2@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@00ABV?$shared_ptr@URenderData@@@tr1@5@@Z)
1>C:\Programming\C++\GraphicsWin32\D3DTechDemo\Debug\D3DTechDemo.exe : fatal error LNK1120: 3 unresolved externals
代码 - 标题
// ------------------------------------------ -------------------------------------------
--- Shader.hpp ---
class Shader {
public:
enum ShaderType { ShaderTypePixel, ShaderTypeVertex, ShaderTypeHull };
public:
Shader( const std::string& filename, const std::string& shaderSrc, const std::string& entrypointFuncName,
const std::string& shaderProfile, const RenderData_sptr& renderData_ptr,
ShaderType sType );
virtual ~Shader( void )
{
mCompiledShader->Release();
delete mCompiledShader;
mCompiledShader = NULL;
}
virtual bool CreateShader( void );
virtual void Recompile( void );
public:
const std::string& Filename;
const std::string& ShaderSrc;
const std::string& EntrypointFuncName;
const std::string& ShaderProfile;
const ShaderType ShdrType;
public:
inline D3DDataBlob*& GetCompiledShader_mutableRef( void )
{ return mCompiledShader; }
inline const D3DDataBlob* const GetCompiledShader_const( void ) const
{ return mCompiledShader; }
inline HRESULT GetCompilerResultMessage( void ) const
{ return mCompilerResultMessage; }
inline const bool IsCompiled( void ) const
{ return mIsCompiled; }
protected:
HRESULT mCompilerResultMessage;
D3DDataBlob* mCompiledShader;
RenderData_sptr mRenderData;
bool mIsCompiled;
};
// ------------------------------------------ -------------------------------------------
- PixelShader.hpp -
class PixelShader : public Shader
{
public:
PixelShader( const std::string& filename, const std::string& shaderSrc, const std::string& entrypointFuncName,
const std::string& shaderProfile, const RenderData_sptr& renderData_ptr );
virtual ~PixelShader()
{
mPixelShader_ptr->Release();
delete mPixelShader_ptr;
mPixelShader_ptr = NULL;
}
bool CreateShader( void );
void Recompile( void );
public:
inline D3DPixelShader* GetPixelShader_ptr( void ) const
{ return mPixelShader_ptr; }
private:
D3DPixelShader* mPixelShader_ptr;
};
// ------------------------------------------ -------------------------------------------
- VertexShader.hpp -
class VertexShader : public Shader
{
public:
VertexShader( const std::string& filename, const std::string& shaderSrc, const std::string& entrypointFuncName,
const std::string& shaderProfile, const RenderData_sptr& renderData_ptr );
virtual ~VertexShader( void )
{
mVertexShader_ptr->Release();
delete mVertexShader_ptr;
mVertexShader_ptr = NULL;
}
virtual bool CreateShader( void );
virtual void Recompile( void );
public:
inline D3DVertexShader*& GetVertexShader_refPtrMutable( void )
{ return mVertexShader_ptr; }
inline const D3DVertexShader* const GetVertexShader_ptrConst( void ) const
{ return mVertexShader_ptr; }
inline D3DVertexShader* GetVertexShader_ptr( void ) const
{ return mVertexShader_ptr; }
private:
D3DVertexShader* mVertexShader_ptr;
};
// ------------------------------------------ -------------------------------------------
代码 - 源文件
Shader.cpp
Shader::Shader( const std::string& filename, const std::string& shaderSrc, const std::string& entrypointFuncName,
const std::string& shaderProfile, const RenderData_sptr& renderData_ptr,
ShaderType sType ) :
Filename( filename ),
ShaderSrc( shaderSrc ),
EntrypointFuncName( entrypointFuncName ),
ShaderProfile( shaderProfile ),
mCompiledShader( NULL ),
mRenderData( renderData_ptr ),
ShdrType( sType ),
mIsCompiled( false )
{
}
bool Shader::CreateShader( void )
{
if( mIsCompiled )
return false;
mCompilerResultMessage = D3DX11CompileFromFileA(
Filename.c_str(),
NULL, NULL,
EntrypointFuncName.c_str(),
ShaderProfile.c_str(),
NULL, NULL, NULL,
&mCompiledShader,
NULL, NULL
);
return true;
}
void Shader::Recompile( void )
{
mIsCompiled = false;
mCompiledShader->Release();
}
// ------------------------------------------ -------------------------------------------
- VertexShader.cpp -
VertexShader::VertexShader( const std::string& filename, const std::string& shaderSrc, const std::string& entrypointFuncName,
const std::string& shaderProfile, const RenderData_sptr& renderData_ptr )
:Shader( filename, entrypointFuncName, shaderSrc,
shaderProfile, renderData_ptr,
ShaderType::ShaderTypeVertex ),
mVertexShader_ptr( NULL )
{
}
bool VertexShader::CreateShader( void )
{
Shader::CreateShader();
D3DDataBlob* errorBuffer = 0;
D3DDataBlob* vertShaderBuffer = 0;
const std::string errorPrefix = "Error Compiling Vertex Shader! - ";
mRenderData->Device->CreateVertexShader(
mCompiledShader->GetBufferPointer(),
mCompiledShader->GetBufferSize(),
NULL,
&mVertexShader_ptr
);
HRESULT vertShaderCompileResult =
D3DX11CompileFromFileA( Filename.c_str(),
0, NULL,
EntrypointFuncName.c_str(),
ShaderProfile.c_str(),
NULL, NULL,
0, &vertShaderBuffer, &errorBuffer, 0 );
if( FAILED( vertShaderCompileResult ) )
{
if( errorBuffer != 0 )
{
OutputDebugStringA( static_cast< char* >( errorBuffer->GetBufferPointer() ) );
errorBuffer->Release();
}
std::cout << errorPrefix + "vertShaderCompileResult failed." << std::endl;
return false;
}
if( errorBuffer != 0 )
errorBuffer->Release();
vertShaderCompileResult = mRenderData->Device->CreateVertexShader(
vertShaderBuffer->GetBufferPointer(),
vertShaderBuffer->GetBufferSize(),
0, &mVertexShader_ptr );
if( FAILED( vertShaderCompileResult ) )
{
if( vertShaderBuffer )
vertShaderBuffer->Release();
std::cout << errorPrefix + "Device->CreateVertexShader( ... ) has failed" << std::endl;
return false;
}
errorBuffer->Release();
vertShaderBuffer->Release();
delete errorBuffer;
delete vertShaderBuffer;
mIsCompiled = true;
return true;
}
void VertexShader::Recompile( void )
{
Shader::Recompile();
mVertexShader_ptr->Release();
/*
if( !this->CreateShader() )
{
//TODO throw error.
}
*/
}
// ------------------------------------------ -------------------------------------------
- PixelShader.cpp -
PixelShader::PixelShader(
const std::string& filename,
const std::string& shaderSrc,
const std::string& entrypointFuncName,
const std::string& shaderProfile,
const RenderData_sptr& renderData_ptr
)
: Shader( filename, shaderSrc, entrypointFuncName, shaderProfile,
renderData_ptr, ShaderType::ShaderTypePixel ),
mPixelShader_ptr( NULL )
{
}
bool PixelShader::CreateShader( void )
{
Shader::CreateShader();
ID3D11InputLayout* inputLayout;
D3DDataBlob* errorBuffer = 0;
D3DDataBlob* pixShaderBuffer = 0;
const std::string errorPrefix = "Error Compiling Pixel Shader! - ";
mRenderData->Device->CreatePixelShader(
mCompiledShader->GetBufferPointer(),
mCompiledShader->GetBufferSize(),
NULL,
&mPixelShader_ptr
);
HRESULT pixShaderCompileResult =
D3DX11CompileFromFileA( Filename.c_str(),
0, NULL,
EntrypointFuncName.c_str(),
ShaderProfile.c_str(),
NULL, NULL,
0, &pixShaderBuffer, &errorBuffer, 0 );
if( FAILED( pixShaderCompileResult ) )
{
if( errorBuffer != 0 )
{
OutputDebugStringA( static_cast< char* >( errorBuffer->GetBufferPointer() ) );
errorBuffer->Release();
}
std::cout << errorPrefix + "pixelShaderCompileResult failed." << std::endl;
return false;
}
if( errorBuffer != 0 )
errorBuffer->Release();
pixShaderCompileResult = mRenderData->Device->CreatePixelShader(
pixShaderBuffer->GetBufferPointer(),
pixShaderBuffer->GetBufferSize(),
0, &mPixelShader_ptr );
if( FAILED( pixShaderCompileResult ) )
{
if( pixShaderBuffer )
pixShaderBuffer->Release();
std::cout << errorPrefix + "Device->CreatePixelShader( ... ) has failed" << std::endl;
return false;
}
errorBuffer->Release();
pixShaderBuffer->Release();
delete errorBuffer;
delete pixShaderBuffer;
mIsCompiled = true;
return true;
}
void PixelShader::Recompile( void )
{
Shader::Recompile();
mPixelShader_ptr->Release();
/*
if( !this->CreateShader() )
{
//TODO throw error.
}
*/
}
更新
由于似乎FileUtility.obj
正在抛出错误,我决定发布它们以期在这里找到一些东西..
FileUtility.hpp
#include <fstream>
#include <iostream>
#include <string>
#include <windows.h>
#include "Render/Shader.hpp"
#include "Render/PixelShader.hpp"
#include "Render/VertexShader.hpp" //<--these shader includes are inlcuded by .cpp as well
namespace stitch
{
//--------------------------------------------------------------
// NOTES:
// - Omit file extension when specifying filename in FileUtility::LoadPixelShader/VertexShader functions - i.e.,
// use the identifier "TriangleVertexShader" as opposed to "TriangleVertexShader.hlsl"
// - Omit file extension when using FileUtility::LoadTextFile.
//--------------------------------------------------------------
class FileUtility
{
public:
//static std::string LoadTextFile( const std::string& filename );
static VertexShader LoadVertexShader( const std::string& filename, const std::string& entrypointFuncName,
const std::string& shaderProfile, const RenderData_sptr& renderData_ptr );
static PixelShader LoadPixelShader( const std::string& filename, const std::string& entrypointFuncName,
const std::string& shaderProfile, const RenderData_sptr& renderData_ptr );
static std::string Win32GetEnv( const char* name );
};
}
FileUtility.cpp
//----------------------------------------------------------------------------------------------------------------------------------
// Static Constant Members
//----------------------------------------------------------------------------------------------------------------------------------
static const std::string& ShaderRoot = FileUtility::Win32GetEnv( "STITCH_SRC" ) + std::string( "\\Resources\\Shaders\\" );
static const std::string& ProjectRootDir = FileUtility::Win32GetEnv( "STITCH_SRC" );
//----------------------------------------------------------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------------------------------------------------------
const int MAX_CHAR_BUF = 65535;
static std::string _GetShaderSrc( const std::string& filename )
{
const std::string shaderFullpath = ShaderRoot + filename + ".fx";
std::ifstream ifs = std::ifstream( shaderFullpath.c_str(), std::ifstream::in );
std::stringstream ss = std::stringstream( std::stringstream::in | std::stringstream::out );
ss << ifs.rdbuf();
ifs.close();
return ss.str();
}
//----------------------------------------------------------------------------------------------------------------------------------
std::string FileUtility::Win32GetEnv( const char* name )
{
static char buf[MAX_CHAR_BUF];
if ( GetEnvironmentVariableA( name, buf, MAX_CHAR_BUF ) ){
return std::string( buf );
}
}
VertexShader FileUtility::LoadVertexShader( const std::string& filename, const std::string& entrypointFuncName,
const std::string& shaderProfile, const RenderData_sptr& renderData_ptr )
{
const std::string shaderSrc = _GetShaderSrc( filename );
VertexShader vs = VertexShader( filename, shaderSrc, entrypointFuncName, shaderProfile, renderData_ptr );
return vs;
}
PixelShader FileUtility::LoadPixelShader( const std::string& filename, const std::string& entrypointFuncName,
const std::string& shaderProfile, const RenderData_sptr& renderData_ptr )
{
const std::string shaderSrc = _GetShaderSrc( filename );
PixelShader ps = PixelShader( filename, shaderSrc, entrypointFuncName, shaderProfile, renderData_ptr );
return ps;
}