Соединить SWIG и Lua
От: DenProg  
Дата: 20.04.09 13:42
Оценка:
Хочу сделать скриптование своей программы с помощью 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);


Test.h:

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

extern void init(lua_State* luaVM);


Test.cpp:
#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 с включенным туда этим файлом? Сделал так, результат тот же. Почему линкер не находит нужную функцию?
Re: Соединить SWIG и Lua
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 20.04.09 14:11
Оценка:
А реализация функции luaopen_test в каком cpp файле находится? Покажи её, пожалуйста.
Re[2]: Соединить SWIG и Lua
От: DenProg  
Дата: 20.04.09 14:31
Оценка:
Здравствуйте, 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)
{
...
}
Re[3]: Соединить SWIG и Lua
От: z00n  
Дата: 20.04.09 17:15
Оценка:
Здравствуйте, DenProg, Вы писали:

DP>Здравствуйте, Nuzhny, Вы писали:


N>>А реализация функции luaopen_test в каком cpp файле находится? Покажи её, пожалуйста.


DP>Она генерится SWIG и находится в test_wrap.cpp, который я подключаю к проекту:


DP>SWIGEXPORT int SWIG_init(lua_State* L)


Поробуйте добавить: /DSTATIC_LINKED
Re[4]: Соединить SWIG и Lua
От: DenProg  
Дата: 20.04.09 18:13
Оценка:
Здравствуйте, z00n, Вы писали:

Z>Поробуйте добавить: /DSTATIC_LINKED


Я забыл сказать, что компилю в студии 2005 .
Re[5]: Соединить SWIG и Lua
От: z00n  
Дата: 20.04.09 20:03
Оценка:
Здравствуйте, DenProg, Вы писали:

DP>Здравствуйте, z00n, Вы писали:


Z>>Поробуйте добавить: /DSTATIC_LINKED


DP>Я забыл сказать, что компилю в студии 2005 .


В свойствах проекта:
Configuration: All Configurations Platform: ...

Configuration Properties -> C/C++ -> Command Line -> Additional options:
/D "STATIC_LINKED"
Re[6]: Соединить SWIG и Lua
От: DenProg  
Дата: 21.04.09 07:28
Оценка:
Здравствуйте, z00n, Вы писали:

Z>В свойствах проекта:

Z>Configuration: All Configurations Platform: ...

Z>Configuration Properties -> C/C++ -> Command Line -> Additional options:

Z>/D "STATIC_LINKED"

Результат тот же. Скажите, я правильно понимаю, что должен перекомпилить Lua с новым *_wrap.cpp файлом всякий раз, когда меняю интерфейс?
Re[7]: Соединить SWIG и Lua
От: z00n  
Дата: 21.04.09 08:03
Оценка: +1
Здравствуйте, 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 файлом всякий раз, когда меняю интерфейс?


Нет, конечно.
Re[8]: Соединить SWIG и Lua
От: DenProg  
Дата: 21.04.09 09:13
Оценка:
Здравствуйте, 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);
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.