Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 链接到Lua5.2.4时出现问题,即使在内联编译源代码时也是如此_C++_C_Lua_Linker_Linker Errors - Fatal编程技术网

C++ 链接到Lua5.2.4时出现问题,即使在内联编译源代码时也是如此

C++ 链接到Lua5.2.4时出现问题,即使在内联编译源代码时也是如此,c++,c,lua,linker,linker-errors,C++,C,Lua,Linker,Linker Errors,我有一个文件configuration.cpp: #include "configuration.hpp" struct game_config* get_game_config(lua_State *L, char* script) { debug("Attempting to load configuration from %s", script); // Execute the script luaL_dofile(L, script); // The

我有一个文件configuration.cpp:

#include "configuration.hpp"

struct game_config* get_game_config(lua_State *L, char* script)
{
    debug("Attempting to load configuration from %s", script);
    // Execute the script
    luaL_dofile(L, script);

    // The environment should now be prepped, we can get the config variables
    struct game_config* game_config;

    lua_getglobal(L, "WINDOW_WIDTH");
    game_config->screen_width = lua_tointeger(L, -1);
    lua_getglobal(L, "WINDOW_HEIGHT");
    game_config->screen_height = lua_tointeger(L, -1);
    lua_getglobal(L, "GAME_TITLE");
    game_config->game_title = lua_tostring(L, -1);

    debug("Loaded config for %s, at %dx%d", game_config->game_title, game_config->screen_width, game_config->screen_height);

    return game_config;
};
其中包括configuration.hpp:

#ifndef CONFIGURATION_HPP_INCLUDED
#define CONFIGURATION_HPP_INCLUDED

#include "common.hpp"
#include "scripting.hpp"

// Data structures

struct game_config {
    int screen_width;
    int screen_height;

    const char *game_title;
};

/*
 * get_config
 * run a script and retrieve configuration data from it
 */

struct game_config *get_game_config(lua_State*, char *);

#endif // CONFIGURATION_HPP_INCLUDED
其中包括
scripting.hpp
,其中以下行导入Lua5.2:

#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
当我将这些行添加到configuration.cpp时,程序将编译并运行。但是,当它们位于任何其他文件(configuration.hpp、scripting.hpp)中时,它不会:

||=== Build: debug in rpfreedom (compiler: GNU GCC Compiler) ===|
src/configuration.cpp||In function ‘game_config* get_game_config(lua_State*, char*)’:|
src/configuration.cpp|13|warning: ‘game_config’ is used uninitialized in this function [-Wuninitialized]|
src/main.cpp||In function ‘int main()’:|
src/main.cpp|13|warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]|
build/debug/configuration.o||In function `get_game_config(lua_State*, char*)':|
/home/leo/projects/rpfreedom/src/configuration.cpp|7|undefined reference to `luaL_loadfilex(lua_State*, char const*, char const*)'|
/home/leo/projects/rpfreedom/src/configuration.cpp|7|undefined reference to `lua_pcallk(lua_State*, int, int, int, int, int (*)(lua_State*))'|
/home/leo/projects/rpfreedom/src/configuration.cpp|12|undefined reference to `lua_getglobal(lua_State*, char const*)'|
/home/leo/projects/rpfreedom/src/configuration.cpp|13|undefined reference to `lua_tointegerx(lua_State*, int, int*)'|
/home/leo/projects/rpfreedom/src/configuration.cpp|14|undefined reference to `lua_getglobal(lua_State*, char const*)'|
/home/leo/projects/rpfreedom/src/configuration.cpp|15|undefined reference to `lua_tointegerx(lua_State*, int, int*)'|
/home/leo/projects/rpfreedom/src/configuration.cpp|16|undefined reference to `lua_getglobal(lua_State*, char const*)'|
/home/leo/projects/rpfreedom/src/configuration.cpp|17|undefined reference to `lua_tolstring(lua_State*, int, unsigned long*)'|
build/debug/scripting.o||In function `scripting_init()':|
/home/leo/projects/rpfreedom/src/scripting.cpp|7|undefined reference to `luaL_newstate()'|
/home/leo/projects/rpfreedom/src/scripting.cpp|20|undefined reference to `lua_settop(lua_State*, int)'|
build/debug/scripting.o||In function `scripting_report_errors(lua_State*, int)':|
/home/leo/projects/rpfreedom/src/scripting.cpp|30|undefined reference to `lua_tolstring(lua_State*, int, unsigned long*)'|
/home/leo/projects/rpfreedom/src/scripting.cpp|31|undefined reference to `lua_settop(lua_State*, int)'|
build/debug/scripting.o:(.rodata+0x88)||undefined reference to `luaopen_base(lua_State*)'|
Makefile|203|recipe for target 'bin/debug/rpfreedom' failed|
Makefile|160|recipe for target 'debug' failed|
||=== Build failed: 15 error(s), 2 warning(s) (0 minute(s), 1 second(s)) ===|
显然,包含configuration.hpp是有效的,因为这里定义的game_config struct没有错误;递归包含也一样,因为debug()宏遵循路径
debug.hpp->common.hpp->configuration.hpp->configuration.cpp
。那么,为什么Lua头文件的#include没有以类似的方式工作呢

我决定调查;我运行了
g++-Iinclude-I/usr/include/lua5.2-esrc/configuration.cpp | grep lua_getglobal
来查看预处理器的输出,结果是。。。他们是。该命令及其在源代码中的使用将返回:

extern void (lua_getglobal) (lua_State *L, const char *var);
所以,我不知道发生了什么


编辑:事实证明,我必须围绕我的
#include
s为Lua做
extern C{}
。但是,现在,仅在configuration.hpp中(不在scripting.hpp中,其中包含Lua头),我收到另一个错误:

include/configuration.hpp:21:37: error: ‘lua_State’ was not declared in this scope
 struct game_config *get_game_config(lua_State*, char *);
但是,scripting.cpp和scripting.hpp中lua_状态的使用不受影响

编辑2:显然,嵌入Lua5.2的推荐方法是在项目中编译它,因为它非常小,所以我这样做了。但是,即使我的Makefile生成的link命令将我的所有对象文件与Lua对象文件明确链接:

g++ build/release/configuration.o build/release/lua5.2.4/lparser.c.o build/release/lua5.2.4/lcode.c.o build/release/lua5.2.4/lundump.c.o build/release/lua5.2.4/lzio.c.o build/release/lua5.2.4/ldo.c.o build/release/lua5.2.4/lapi.c.o build/release/lua5.2.4/lgc.c.o build/release/lua5.2.4/lfunc.c.o build/release/lua5.2.4/ldump.c.o build/release/lua5.2.4/ltable.c.o build/release/lua5.2.4/lcorolib.c.o build/release/lua5.2.4/loslib.c.o build/release/lua5.2.4/liolib.c.o build/release/lua5.2.4/ltm.c.o build/release/lua5.2.4/lmem.c.o build/release/lua5.2.4/lctype.c.o build/release/lua5.2.4/lauxlib.c.o build/release/lua5.2.4/ldebug.c.o build/release/lua5.2.4/lobject.c.o build/release/lua5.2.4/loadlib.c.o build/release/lua5.2.4/linit.c.o build/release/lua5.2.4/lmathlib.c.o build/release/lua5.2.4/llex.c.o build/release/lua5.2.4/lstate.c.o build/release/lua5.2.4/lopcodes.c.o build/release/lua5.2.4/lstrlib.c.o build/release/lua5.2.4/lbaselib.c.o build/release/lua5.2.4/ltablib.c.o build/release/lua5.2.4/ldblib.c.o build/release/lua5.2.4/lbitlib.c.o build/release/lua5.2.4/lvm.c.o build/release/lua5.2.4/lstring.c.o build/release/scripting.o build/release/main.o  -L/usr/lib/x86_64-linux-gnu -Lm -Ldl -lsfml-graphics -lsfml-window -lsfml-audio -lsfml-network -lsfml-system   -o bin/release/rpfreedom
我得到的链接器错误与我之前得到的相同


链接器的参数顺序重要吗?

显示的错误消息似乎来自链接器,而不是编译器

一切都成功地包括在内。一切都顺利完成了。但是链接失败,因为某些必需的库没有链接到

请注意,错误消息引用:

build/debug/configuration.o
...
build/debug/scripting.o
...
。。。而不是您的源代码(错误中提到的cpp具有误导性,它们实际上是从.o文件中的调试信息中提取的)。错误消息通常是来自链接器的错误消息


你的源代码很好。您需要修复makefile。

嗯,您的第一个警告正是编译器告诉您的。您的代码如下:

// The environment should now be prepped, we can get the config variables
struct game_config* game_config;

lua_getglobal(L, "WINDOW_WIDTH");
game_config->screen_width = lua_tointeger(L, -1);
警告是:

‘game_config’ is used uninitialized in this function.
在访问
screen\u width
之前,您没有将指针
game\u config
设置为指向任何对象。也许您需要将其设置为
newgame\u config()
。我更愿意在堆栈上创建一个,并按值返回:

game_config config;
lua_getglobal(L, "WINDOW_WIDTH");
config.screen_width = lua_tointeger(L, -1);
...
return config;

不管是哪种方式,让游戏标题成为一个
std::string
可能比一个
const char*
更好。我最终自己编译了一个静态Lua(
liblua.a
),创建了一个lib/目录,并将
-Llib-llua
添加到我的链接器行,从而纠正了这个问题。这将需要额外的努力来实现跨平台,但目前还可以。

结果表明,我必须围绕我的
#include
s为Lua做
extern C{}
。但是,现在,只有在configuration.hpp中(不在scripting.hpp中,其中包含Lua头),我才收到另一个错误;我把它编辑成主要问题。非常感谢。您也可以使用
#include“lua.hpp”
,它可以为您做到这一点。当然,我打算在编译程序并与lua库链接后尽快解决这一问题。