Хочу сделать скриптование своей программы с помощью Lua. Связываю с оной через Swig. Беру примеры из документации.
В пребилде проекта:
swig -lua -c++ tests/test.i
Test.i:
%module test
%{
/* Put headers and other declarations here */
extern double My_variable;
extern int fact(int);
extern int my_mod(int n, int m);
%}
extern double My_variable;
extern int fact(int);
extern int my_mod(int n, int m);
#include"test.h"extern int luaopen_test(lua_State* L);
double My_variable = 3.0;
/* Compute factorial of n */int fact(int n)
{
if (n <= 1)
return 1;
else
return n * fact(n - 1);
}
/* Compute n mod m */int my_mod(int n, int m)
{
return(n % m);
}
void init(lua_State* luaVM)
{
...
luaopen_base(luaVM);
luaopen_test(luaVM);
...
}
Компиляция упирается в ошибку линкера: 1>test.obj : error LNK2019: unresolved external symbol "int __cdecl luaopen_test(struct lua_State *)" (?luaopen_test@@YAHPAUlua_State@@@Z) referenced in function "void __cdecl init(struct lua_State *)" (?init@@YAXPAUlua_State@@@Z)
Файл test_wrap.cxx в проект включен. Или надо перекомпилить Lua с включенным туда этим файлом? Сделал так, результат тот же. Почему линкер не находит нужную функцию?
Здравствуйте, Nuzhny, Вы писали:
N>А реализация функции luaopen_test в каком cpp файле находится? Покажи её, пожалуйста.
Она генерится SWIG и находится в test_wrap.cpp, который я подключаю к проекту:
#define SWIG_init luaopen_test
/* Forward declaration of where the user's %init{} gets inserted */void SWIG_init_user(lua_State* L );
#ifdef __cplusplus
extern"C" {
#endif/* this is the initialization function
added at the very end of the code
the function is always called SWIG_init, but an eariler #define will rename it
*/
SWIGEXPORT int SWIG_init(lua_State* L)
{
...
}
Здравствуйте, DenProg, Вы писали:
DP>Здравствуйте, Nuzhny, Вы писали:
N>>А реализация функции luaopen_test в каком cpp файле находится? Покажи её, пожалуйста.
DP>Она генерится SWIG и находится в test_wrap.cpp, который я подключаю к проекту:
DP>SWIGEXPORT int SWIG_init(lua_State* L)
Здравствуйте, DenProg, Вы писали:
DP>Здравствуйте, z00n, Вы писали:
Z>>Поробуйте добавить: /DSTATIC_LINKED
DP>Я забыл сказать, что компилю в студии 2005 .
В свойствах проекта:
Configuration: All Configurations Platform: ...
Здравствуйте, DenProg, Вы писали:
DP>Здравствуйте, z00n, Вы писали:
Z>>В свойствах проекта: Z>>Configuration: All Configurations Platform: ...
Z>>Configuration Properties -> C/C++ -> Command Line -> Additional options: Z>>/D "STATIC_LINKED"
DP>Результат тот же.
Странно, тогда попробуите просто стереть SWIGEXPORT перед тем, как компилировать файл.
Скорее всего прблема в том, что SWIGEXPORT у вас раскрывается препроцессором в "__declspec(dllexport)".
SWIGEXPORT int SWIG_init(lua_State* L)
DP>Скажите, я правильно понимаю, что должен перекомпилить Lua с новым *_wrap.cpp файлом всякий раз, когда меняю интерфейс?
Здравствуйте, z00n, Вы писали:
Z>Здравствуйте, DenProg, Вы писали:
DP>>Здравствуйте, z00n, Вы писали:
Z>>>В свойствах проекта: Z>>>Configuration: All Configurations Platform: ...
Z>>>Configuration Properties -> C/C++ -> Command Line -> Additional options: Z>>>/D "STATIC_LINKED"
DP>>Результат тот же. Z>Странно, тогда попробуите просто стереть SWIGEXPORT перед тем, как компилировать файл. Z>Скорее всего прблема в том, что SWIGEXPORT у вас раскрывается препроцессором в "__declspec(dllexport)".
Z>
Z>SWIGEXPORT int SWIG_init(lua_State* L)
Z>
DP>>Скажите, я правильно понимаю, что должен перекомпилить Lua с новым *_wrap.cpp файлом всякий раз, когда меняю интерфейс?
Z>Нет, конечно.
Спасибо за помощь! Бага была в том, что SWIG заворачивает нужную функцию в extern "C":
#ifdef __cplusplus
extern"C" {
#endif/* this is the initialization function
added at the very end of the code
the function is always called SWIG_init, but an eariler #define will rename it
*/
SWIGEXPORT int SWIG_init(lua_State* L)
{
}
#ifdef __cplusplus
}
#endif
значит и я ее должен объявлять:
extern"C"
{
extern int luaopen_test(lua_State* L);
}