2016-01-17 88 views
1

我一直在爲通用應用程序編寫一些C和C++基礎結構。目前這是一個正在進行中的工作,由配置分析與Lua,日誌記錄功能和一個使用我自己的網絡協議/消息API的客戶端/服務器API組成。圖書館/鏈接器問題混合C和C++

我已將代碼組織到兩個庫中:一個用於C代碼(libmarlin.so),一個用於C++代碼(libmarlin ++。so)。我之所以有兩個而不是一個是因爲我仍然只使用C++庫的原始問題:將應用程序鏈接到它會導致Lua代碼或C庫中的代碼的「未定義引用」錯誤,以及一些其他隨機C++「operator new」參考,具體取決於Makefile中-l開關的排序。我無法找到滿足依賴關係的組合。我已經瞭解這些交換機的排序的重要性,並根據本網站上的問題提出了建議。一切都無濟於事。

我會粘貼我認爲與此相關的內容以保存複製大量代碼。如果你還需要其他的東西,或者你可以克隆我的GitHub倉庫:https://github.com/adamd1008/marlin。您需要在回購站外的名爲lua-5.3.2的文件夾中使用Lua代碼,或者根據需要更改Makefiles。另外請注意,我修改了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庫,仍然存在問題(儘管我不確定它在構建動態庫時是否有任何影響?)。

任何指針將不勝感激。

回答

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

哦,上帝,是的,我錯過了一個:(通常我不會錯過任何頭,感謝 – Doddy

+0

@Doddy高興幫助:) –

2

如果你想在你的C++程序中使用C代碼,你應該聲明所有的C原型爲extern "C"。因此,嘗試所有包裹的Lua包括在你的程序是這樣的:

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

。 #include '(至少lua 5.1,5.2和5.3)應該完成相同的操作。 –