首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用对` `CEGUI::NullRenderer::create()‘的make: Undefined引用生成时出错

使用对` `CEGUI::NullRenderer::create()‘的make: Undefined引用生成时出错
EN

Stack Overflow用户
提问于 2021-04-30 23:28:36
回答 1查看 27关注 0票数 0

最近,有人让我想起了我在成长过程中(不久前)经常玩的一款游戏,我想尝试让它再次运行。它已经有近十年没有开发过了,所以没有一个预构建的包可以工作。我抓起了游戏和CEGUI库的一个旧版本的源代码,开始工作。

我修复了make过程中的一些问题,但现在我遇到了这个错误消息:

代码语言:javascript
复制
/usr/bin/ld: smc-video.o: in function `SMC::cVideo::Init_CEGUI_Fake() const':
video.cpp:107: undefined reference to `CEGUI::NullRenderer::create()'

我几乎没有使用C++的经验,但我设法理解这是一个链接器问题,无法找到函数声明。所以我看了一下应该有声明的文件,确实有一个create函数:

代码语言:javascript
复制
/*!
\brief
    Create an NullRenderer object 
*/
static NullRenderer& create();

但是它不会遗漏一个声明吗?我检查了链接器在正确的文件中查找函数,因为将{}添加到代码中确实可以防止错误(当然,它确实会导致不同的错误),这让我相信make没有任何错误。我还在CEGUINullRenderer.h的includes中查找了声明,但没有找到。(没有CEGUINullRenderer.cpp)

我尝试只从create函数返回一个NullRenderer对象,但这并不能真正起作用。这里我漏掉了什么?

video.cpp (直到抛出错误的部分):

代码语言:javascript
复制
/***************************************************************************
 * video.cpp  -  General video functions
 *
 * Copyright (C) 2005 - 2011 Florian Richter
 ***************************************************************************/
/*
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.
   
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "../video/video.h"
#include "../gui/hud.h"
#include "../user/preferences.h"
#include "../core/framerate.h"
#include "../video/font.h"
#include "../core/game_core.h"
#include "../video/img_settings.h"
#include "../input/mouse.h"
#include "../video/renderer.h"
#include "../core/main.h"
#include "../core/math/utilities.h"
#include "../core/i18n.h"
#include "../core/math/size.h"
#include "../core/filesystem/filesystem.h"
#include "../core/filesystem/resource_manager.h"
#include "../gui/spinner.h"
// SDL
#include "SDL_opengl.h"
// CEGUI
#include "CEGUIDefaultResourceProvider.h"
#include "CEGUIDefaultLogger.h"
#include "CEGUIExceptions.h"
#include "CEGUIWindowFactoryManager.h"
#include "CEGUIImagesetManager.h"
#include "CEGUIFontManager.h"
#include "CEGUIWindowManager.h"
#include "CEGUISchemeManager.h"
#include "falagard/CEGUIFalWidgetLookManager.h"
#include "elements/CEGUIProgressBar.h"
#include "RendererModules/Null/CEGUINullRenderer.h"
// png
#include <png.h>
#ifndef PNG_COLOR_TYPE_RGBA
    #define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA
#endif

namespace SMC
{

/* *** *** *** *** *** *** *** Video class *** *** *** *** *** *** *** *** *** *** */

cVideo :: cVideo( void )
{
    m_opengl_version = 0;

    m_double_buffer = 0;

    m_rgb_size[0] = 0;
    m_rgb_size[1] = 0;
    m_rgb_size[2] = 0;

    m_default_buffer = GL_BACK;
    m_max_texture_size = 512;
    
    m_audio_init_failed = 0;
    m_joy_init_failed = 0;
    m_geometry_quality = cPreferences::m_geometry_quality_default;
    m_texture_quality = cPreferences::m_texture_quality_default;

    SDL_VERSION( &wm_info.version );
#ifdef __unix__
    glx_context = NULL;
#endif
    m_render_thread = boost::thread();

    m_initialised = 0;
}

cVideo :: ~cVideo( void )
{

}

void cVideo :: Init_CEGUI_Fake( void ) const
{
    // create fake Resource Provider
    CEGUI::DefaultResourceProvider *rp = new CEGUI::DefaultResourceProvider();
    // set Resource Provider directories
    if( CEGUI::System::getDefaultXMLParserName().compare( "XercesParser" ) == 0 )
    {
        // This is needed for Xerces to specify the schemas location
        rp->setResourceGroupDirectory( "schemas", DATA_DIR "/" GAME_SCHEMA_DIR "/" );
    }
    // get a directory to dump the CEGUI log
#ifdef _WIN32
    // fixme : Workaround for std::string to CEGUI::String utf8 conversion. Check again if CEGUI 0.8 works with std::string utf8
    CEGUI::String log_dump_dir = (const CEGUI::utf8*)((Get_Temp_Directory() + "cegui.log").c_str());
#else
    CEGUI::String log_dump_dir = "/dev/null";
#endif
    // create fake system and renderer
    pGuiSystem = &CEGUI::System::create( CEGUI::NullRenderer::create(), rp, NULL, NULL, NULL, "", log_dump_dir );
}

CEGUINullRenderer.h:

代码语言:javascript
复制
/***********************************************************************
    filename:   CEGUINullRenderer.h
    created:    Fri Jan 15 2010
    author:     Eugene Marcotte
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2010 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#ifndef _CEGUINullRenderer_h_
#define _CEGUINullRenderer_h_

#include "../../CEGUIRenderer.h"
#include "../../CEGUISize.h"
#include "../../CEGUIVector.h"

#include <vector>
#include <map>

#if (defined( __WIN32__ ) || defined( _WIN32 )) && !defined(CEGUI_STATIC)
#   ifdef NULL_GUIRENDERER_EXPORTS
#       define NULL_GUIRENDERER_API __declspec(dllexport)
#   else
#       define NULL_GUIRENDERER_API __declspec(dllimport)
#   endif
#else
#   define NULL_GUIRENDERER_API
#endif

#if defined(_MSC_VER)
#   pragma warning(push)
#   pragma warning(disable : 4251)
#endif


// Start of CEGUI namespace section
namespace CEGUI
{
class NullGeometryBuffer;
class NullTexture;
class NullRenderTarget;

//! CEGUI::Renderer implementation for no particular engine
class NULL_GUIRENDERER_API NullRenderer : public Renderer
{
public:
    /*!
    \brief
        Convenience function that creates all the necessary objects
        then initialises the CEGUI system with them.

        This will create and initialise the following objects for you:
        - CEGUI::NullRenderer
        - CEGUI::DefaultResourceProvider
        - CEGUI::System

    \return
        Reference to the CEGUI::NullRenderer object that was created.

    */
    static NullRenderer& bootstrapSystem();
    
    /*!
    \brief
        Convenience function to cleanup the CEGUI system and related objects
        that were created by calling the bootstrapSystem function.

        This function will destroy the following objects for you:
        - CEGUI::System
        - CEGUI::DefaultResourceProvider
        - CEGUI::NullRenderer

    \note
        If you did not initialise CEGUI by calling the bootstrapSystem function,
        you should \e not call this, but rather delete any objects you created
        manually.
    */
    static void destroySystem();

    /*!
    \brief
        Create an NullRenderer object 
    */
    static NullRenderer& create();

    //! destory an NullRenderer object.
    static void destroy(NullRenderer& renderer);

    // implement CEGUI::Renderer interface
    RenderingRoot& getDefaultRenderingRoot();
    GeometryBuffer& createGeometryBuffer();
    void destroyGeometryBuffer(const GeometryBuffer& buffer);
    void destroyAllGeometryBuffers();
    TextureTarget* createTextureTarget();
    void destroyTextureTarget(TextureTarget* target);
    void destroyAllTextureTargets();
    Texture& createTexture();
    Texture& createTexture(const String& filename, const String& resourceGroup);
    Texture& createTexture(const Size& size);
    void destroyTexture(Texture& texture);
    void destroyAllTextures();
    void beginRendering();
    void endRendering();
    void setDisplaySize(const Size& sz);
    const Size& getDisplaySize() const;
    const Vector2& getDisplayDPI() const;
    uint getMaxTextureSize() const;
    const String& getIdentifierString() const;

protected:
    //! default constructor.
    NullRenderer();
    //! common construction things.
    void constructor_impl();
    //! destructor.
    virtual ~NullRenderer();

    //! String holding the renderer identification text.
    static String d_rendererID;
    //! What the renderer considers to be the current display size.
    Size d_displaySize;
    //! What the renderer considers to be the current display DPI resolution.
    Vector2 d_displayDPI;
    //! The default rendering root object
    RenderingRoot* d_defaultRoot;
    //! The default RenderTarget (used by d_defaultRoot)
    NullRenderTarget* d_defaultTarget;
    //! container type used to hold TextureTargets we create.
    typedef std::vector<TextureTarget*> TextureTargetList;
    //! Container used to track texture targets.
    TextureTargetList d_textureTargets;
    //! container type used to hold GeometryBuffers we create.
    typedef std::vector<NullGeometryBuffer*> GeometryBufferList;
    //! Container used to track geometry buffers.
    GeometryBufferList d_geometryBuffers;
    //! container type used to hold Textures we create.
    typedef std::vector<NullTexture*> TextureList;
    //! Container used to track textures.
    TextureList d_textures;
    //! What the renderer thinks the max texture size is.
    uint d_maxTextureSize;
};


} // End of  CEGUI namespace section

#if defined(_MSC_VER)
#   pragma warning(pop)
#endif

#endif  // end of guard _CEGUINullRenderer_h_
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-01 04:33:35

您已经声明了它,这意味着编译器很乐意编译它。声明类似于函数的名称:编译器知道函数存在,并且可以编译调用它的代码。

但是为了链接它,您必须在该函数的定义(实现)中进行链接。链接器告诉您,它没有您声明的那个函数的实际实现。

很可能您的链接行是错误的,几乎可以肯定的是,您要么根本忘了将库放在链接行上,要么就是把它放在了错误的位置,但是由于您没有向我们提供有关用于生成错误消息的link命令或用于链接的makefile规则的任何信息,因此我们无能为力。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67336566

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档