New issue 9: when Selectively Exporting C Functions to lua in Member functions of two classes in the same namespace, the compiler report a linking error https://bitbucket.org/liamdevine/oolua/issue/9/when-selectively-exporting-c-functions-to Oscar Zhao: The circumstance is such: There are several C++ functions to export to lua and two classes ( LuaWrapper, YourLuaWrapper). In the member functions of LuaWrapper( and YourLuaWrapper), I want to export the C++ functions defined before. Then I put the OOLUA_CFUNC(...) in a single header file, and let the LuaWrapper.cpp and YourLuaWrapper.cpp include the header file. There are corresponding "OOLUA::set_global(..)" in the definition of member functions. <br />Before this, I always put OOLUA_CFUNC and OOLUA::set_global in the same cpp file, and no problems found. The error is the following: ``` #!lua 1>------ Build started: Project: ExportCFuncInFunctions, Configuration: Debug Win32 ------ 1>Compiling... 1>LuaWrapper.cpp 1>YourLuaWrapper.cpp 1>Generating Code... 1>Linking... 1>YourLuaWrapper.obj : error LNK2005: "bool __cdecl ttservice::isBool(void)" (?isBool@ttservice@@YA_NXZ) already defined in LuaWrapper.obj 1>YourLuaWrapper.obj : error LNK2005: "bool __cdecl ttservice::isInt(void)" (?isInt@ttservice@@YA_NXZ) already defined in LuaWrapper.obj 1>YourLuaWrapper.obj : error LNK2005: "bool __cdecl ttservice::isDouble(void)" (?isDouble@ttservice@@YA_NXZ) already defined in LuaWrapper.obj 1>YourLuaWrapper.obj : error LNK2005: "bool __cdecl ttservice::isString(void)" (?isString@ttservice@@YA_NXZ) already defined in LuaWrapper.obj 1>YourLuaWrapper.obj : error LNK2005: "int __cdecl ttservice::oolua_isBool(struct lua_State *)" (?oolua_isBool@ttservice@@YAHPAUlua_State@@@Z) already defined in LuaWrapper.obj 1>YourLuaWrapper.obj : error LNK2005: "int __cdecl ttservice::oolua_isInt(struct lua_State *)" (?oolua_isInt@ttservice@@YAHPAUlua_State@@@Z) already defined in LuaWrapper.obj 1>YourLuaWrapper.obj : error LNK2005: "int __cdecl ttservice::oolua_isDouble(struct lua_State *)" (?oolua_isDouble@ttservice@@YAHPAUlua_State@@@Z) already defined in LuaWrapper.obj 1>YourLuaWrapper.obj : error LNK2005: "int __cdecl ttservice::oolua_isString(struct lua_State *)" (?oolua_isString@ttservice@@YAHPAUlua_State@@@Z) already defined in LuaWrapper.obj 1>E:\work\Git\OOLua\OOLuaTest\_runtime\Debug\\ExportCFuncInFunctions.exe : fatal error LNK1169: one or more multiply defined symbols found 1>Build log was saved at "file://E:\work\Git\OOLua\OOLuaTest\_builder\Debug\ExportCFuncInFunctions\BuildLog.htm" 1>ExportCFuncInFunctions - 9 error(s), 0 warning(s) ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== ``` **SOURCE Code:** FunctionsToExport.h ``` #!c++ #ifndef FUNCTIONS_TO_EXPORT_H__ #define FUNCTIONS_TO_EXPORT_H__ #include "oolua.h" namespace ttservice { bool isBool(){ return true; } bool isInt(){ return true; } bool isDouble(){ return true; } bool isString(){ return true; } } #endif ``` FunctionsRegist.h ``` #!c++ #ifndef FUNCTION_REGIST_H_ #define FUNCTION_REGIST_H_ #include "oolua.h" #include "FunctionsToExport.h" namespace ttservice { OOLUA_CFUNC(isBool, oolua_isBool) OOLUA_CFUNC(isInt, oolua_isInt) OOLUA_CFUNC(isDouble, oolua_isDouble) OOLUA_CFUNC(isString, oolua_isString) } #endif ``` LuaWrapper.h ``` #!c++ #ifndef LUA_WRAPPER_H_ #define LUA_WRAPPER_H_ #include "oolua.h" namespace ttservice { class LuaWrapper { public: LuaWrapper(): vm(new OOLUA::Script){} ~LuaWrapper(); void regist_one_function(); void regist_all_functions(); private: OOLUA::Script* vm; }; } #endif ``` LuaWrapper.cpp ``` #!c++ #include "LuaWrapper.h" #include "oolua.h" #include "FunctionsRegist.h" namespace ttservice { LuaWrapper::~LuaWrapper() { if(vm) delete vm; } void LuaWrapper::regist_one_function() { OOLUA::set_global(*vm, "isBool", oolua_isBool); } void LuaWrapper::regist_all_functions() { OOLUA::set_global(*vm, "isBool", oolua_isBool); OOLUA::set_global(*vm, "isInt", oolua_isInt); OOLUA::set_global(*vm, "isDouble", oolua_isDouble); OOLUA::set_global(*vm, "isString", oolua_isString); } } ``` YourLuaWrapper.h ``` #!c++ #ifndef YOUR_LUA_WRAPPER_H_ #define YOUR_LUA_WRAPPER_H_ #include "oolua.h" namespace ttservice { class YourLuaWrapper { YourLuaWrapper():vm(new OOLUA::Script){} ~YourLuaWrapper(); void regist_one_function(); void regist_all_functions(); private: OOLUA::Script* vm; }; } #endif ``` YourLuaWrapper.cpp ``` #!c++ #include "YourLuaWrapper.h" #include "oolua.h" #include "FunctionsRegist.h" namespace ttservice { YourLuaWrapper::~YourLuaWrapper() { if(vm) delete vm; } void YourLuaWrapper::regist_one_function() { OOLUA::set_global(*vm, "isBool", oolua_isBool); } void YourLuaWrapper::regist_all_functions() { OOLUA::set_global(*vm, "isBool", oolua_isBool); OOLUA::set_global(*vm, "isInt", oolua_isInt); OOLUA::set_global(*vm, "isDouble", oolua_isDouble); OOLUA::set_global(*vm, "isString", oolua_isString); } } ```