混合C和C ++的库/链接器问题

时间:2016-01-17 19:53:49

标签: c++ c linker

我一直在为通用应用程序编写一些C和C ++基础结构。目前,这是一项正在进行的工作,包括使用Lua进行配置解析,记录功能以及使用我自己的网络协议/消息传递API的客户端/服务器API。

我已将代码组织成两个库:一个用于C代码(libmarlin.so),另一个用于C ++代码(libmarlin ++。so)。我有两个而不是一个的原因恰好是我仍然只使用C ++库的原始问题:将应用程序链接到它将导致Lua代码或我的C库中的代码加上一些“未定义的引用”错误其他随机C ++“operator new”引用,具体取决于Makefile中-l开关的顺序。我找不到满足依赖关系的组合。我已经了解订购这些交换机的重要性,并根据本网站上的问题尝试了建议;一切都无济于事。

我将粘贴我认为与此相关的内容,以节省大量复制代码。如果您还需要其他任何问题,或者您可以克隆我的GitHub存储库:https://github.com/adamd1008/marlin。您需要在名为lua-5.3.2的repo之外的文件夹中使用Lua代码,或者根据需要更改Makefile。另请注意,我修改了Lua makefile以构建动态库而不是默认的静态库,因此我在构建时使用了-llua。 (这只是为了尝试解决潜在的问题。)

汇编:

make -C src
make[1]: Entering directory `/home/adam/marlin/src'
** Compiling file 'log.c'
gcc -std=c99 -g -c -Wall -Wextra -Werror -rdynamic -fPIC -I../../lua-5.3.2/src -DMAJOR_VER=1 -DMINOR_VER=0 -DBUILD_VER=0 -DLOG_UUID=\"27dc17c4-bd53-11e5-bb37-a02bb831a7e4\" log.c -o log.o
** Compiling file 'msg.c'
gcc -std=c99 -g -c -Wall -Wextra -Werror -rdynamic -fPIC -I../../lua-5.3.2/src -DMAJOR_VER=1 -DMINOR_VER=0 -DBUILD_VER=0 -DLOG_UUID=\"27dc17c4-bd53-11e5-bb37-a02bb831a7e4\" msg.c -o msg.o
** Linking file 'libmarlin.so.1.0.0'
gcc -shared -Wl,-soname,libmarlin.so.1.0.0 -o ../lib/libmarlin.so.1.0.0 log.o msg.o
ln -sf libmarlin.so.1.0.0 ../lib/libmarlin.so
** Compiling file 'M_App.cpp'
g++ -std=c++11 -g -c -Wall -Wextra -Werror -rdynamic -fPIC -pedantic -I../../lua-5.3.2/src -DMAJOR_VER=1 -DMINOR_VER=0 -DBUILD_VER=0 M_App.cpp -o M_App.o
** Compiling file 'M_Field.cpp'
g++ -std=c++11 -g -c -Wall -Wextra -Werror -rdynamic -fPIC -pedantic -I../../lua-5.3.2/src -DMAJOR_VER=1 -DMINOR_VER=0 -DBUILD_VER=0 M_Field.cpp -o M_Field.o
** Compiling file 'M_FieldMap.cpp'
g++ -std=c++11 -g -c -Wall -Wextra -Werror -rdynamic -fPIC -pedantic -I../../lua-5.3.2/src -DMAJOR_VER=1 -DMINOR_VER=0 -DBUILD_VER=0 M_FieldMap.cpp -o M_FieldMap.o
** Compiling file 'M_Msg.cpp'
g++ -std=c++11 -g -c -Wall -Wextra -Werror -rdynamic -fPIC -pedantic -I../../lua-5.3.2/src -DMAJOR_VER=1 -DMINOR_VER=0 -DBUILD_VER=0 M_Msg.cpp -o M_Msg.o
** Compiling file 'M_MsgApp.cpp'
g++ -std=c++11 -g -c -Wall -Wextra -Werror -rdynamic -fPIC -pedantic -I../../lua-5.3.2/src -DMAJOR_VER=1 -DMINOR_VER=0 -DBUILD_VER=0 M_MsgApp.cpp -o M_MsgApp.o
** Linking file 'libmarlin++.so.1.0.0'
gcc -shared -L../../lua-5.3.2/src -llua -Wl,-soname,libmarlin++.so.1.0.0 -o ../lib/libmarlin++.so.1.0.0 M_App.o M_Field.o M_FieldMap.o M_Msg.o M_MsgApp.o
ln -sf libmarlin++.so.1.0.0 ../lib/libmarlin++.so
make -C test
make[2]: Entering directory `/home/adam/marlin/src/test'
** Compiling file 'msg_test.c'
gcc -std=c99 -g -c -Wall -Wextra -Werror -rdynamic -I../../../lua-5.3.2/src msg_test.c -o msg_test.o
** Linking file 'msg_test.o'
gcc -L../../lib -L../../../lua-5.3.2/src -lm -ldl -llua -lmarlin -o msg_test msg_test.o
** Compiling file 'app_test.cpp'
g++ -std=c++11 -g -c -Wall -Wextra -Werror -rdynamic -pedantic -I../../../lua-5.3.2/src app_test.cpp -o app_test.o
** Linking file 'app_test.o'
g++ -L../../lib -L../../../lua-5.3.2/src -lm -ldl -llua -lmarlin -lmarlin++ -o app_test app_test.o
../../lib/libmarlin++.so: undefined reference to `lua_tolstring(lua_State*, int, unsigned long*)'
../../lib/libmarlin++.so: undefined reference to `lua_type(lua_State*, int)'
../../lib/libmarlin++.so: undefined reference to `luaL_loadfilex(lua_State*, char const*, char const*)'
../../lib/libmarlin++.so: undefined reference to `lua_getglobal(lua_State*, char const*)'
../../lib/libmarlin++.so: undefined reference to `lua_geti(lua_State*, int, long long)'
../../lib/libmarlin++.so: undefined reference to `luaL_openlibs(lua_State*)'
../../lib/libmarlin++.so: undefined reference to `lua_typename(lua_State*, int)'
../../lib/libmarlin++.so: undefined reference to `lua_settop(lua_State*, int)'
../../lib/libmarlin++.so: undefined reference to `lua_close(lua_State*)'
../../lib/libmarlin++.so: undefined reference to `lua_pushstring(lua_State*, char const*)'
../../lib/libmarlin++.so: undefined reference to `lua_gettable(lua_State*, int)'
../../lib/libmarlin++.so: undefined reference to `luaL_newstate()'
collect2: error: ld returned 1 exit status
make[2]: *** [app_test] Error 1
make[2]: Leaving directory `/home/adam/marlin/src/test'
make[1]: *** [test] Error 2
make[1]: Leaving directory `/home/adam/marlin/src'
make: *** [all] Error 2

我怀疑有一个简单的解释,但我无法解决。根据上一个编译步骤,-llua在我的任一个库之前指定,但是libmarlin ++。所以即使它本身也链接到Lua库仍然有问题(虽然我不确定它有什么影响时建立一个动态库?)。

任何指针都会非常感激。

2 个答案:

答案 0 :(得分:4)

你的Github存储库中有很多代码,所以彻底的分析需要时间,但是,初看起来,这似乎是“失踪的情况extern "C"”(双关语)。

从C ++代码中,当包含C头时,您需要extern "C"。有几种方法可以做到这一点。首先,包括,如:

extern "C" {
#include "the_c_header.h"
}

其次,在标题中:

#if defined(__cplusplus)
extern "C" {
#endif

.... contents of the C header...

#if defined(__cplusplus)
}
#endif

第三是耗费时间来说明,基本上,将extern "C"添加到C头中的任何声明。

可能还有其他问题,但是,我先试试这个。

答案 1 :(得分:2)

如果要在C ++程序中使用C代码,则应将所有C原型声明为extern "C"。因此,尝试将所有Lua包含在您的程序中,如下所示:

extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}