Swig C ++ Lua Pass класс по ссылке - PullRequest
2 голосов
/ 07 августа 2009

Я не знаю, почему мне тяжело с этим. Все, что я хочу сделать, это:

class foo {

public:
    foo(){}
    ~foo(){}
    float a,b;
};

class foo2 {
public:
     foo2(){}
     foo2(const foo &f){*this = f;}
     ~foo2(){}
     void operator=(const foo& f){
          x = f.a;
          y = f.b;
     }
     float x,y;
};

/* Usage(cpp):

   foo f;
   foo2 f2(f);

   //or using the = operator
   f2 = f;
*/

Проблема, с которой я столкнулся, заключается в том, что после перебора этого кода я не могу понять, как заставить скрипт lua играть хорошо.

/* Usage(lua)
   f = example.foo()
   f2 = example.foo2(f) --error
*/

Ошибка, которую я получаю: «Неправильные аргументы для перегруженной функции« new_Foo2 »»: Возможные прототипы c / c ++: foo2 () foo2 (foo const &)

То же самое происходит, если я пытаюсь использовать do f2 = f. Как я понимаю, все хранится в виде указателя, поэтому я попытался добавить дополнительный конструктор, который взял указатель на foo, но безрезультатно.

Ответы [ 5 ]

1 голос
/ 08 августа 2009

Бог знает только, что делает SWIG. Мой совет - прикусить пулю и использовать Lua C API , который также работает с C ++. Его не так сложно выучить, и вы сможете перегружать метод foo2 точно так, как вы хотите. Хорошие примеры можно найти в книге Роберто Иерусалимского Программирование на Lua ; Вы можете получить предыдущее издание бесплатно онлайн .

N.B. Поскольку API - это C, он не знает из справочных параметров. Ваш объект пользовательских данных Lua должен содержать указатель на объект C ++ класса foo2.

1 голос
/ 08 августа 2009

В соответствии с предложением использовать собственный API C для Lua, но, поскольку вы находитесь на C ++, попробуйте Luabind . Это работает очень хорошо, как только вы освоите его. Если вы попробуете, убедитесь, что вы получили последнюю версию - она ​​активно поддерживается и постоянно улучшается.

1 голос
/ 07 августа 2009

В конструкторе копирования у вас есть оператор ссылки в неправильном месте, поместите его после 'foo'. Поскольку ваш код стоит, он не компилируется, по крайней мере, для меня на VS 2008.

Редактировать: Понятно, спасибо за обновление. Ну, я не особенно знаком с LUA, но я знаю, что при переносе с C ++ на C # есть несколько вещей, которые меняются, когда дело доходит до ссылок. Поэтому моя единственная идея заключается в том, чтобы показать, что вы передаете переменную с помощью ref / const ref. То есть. в C # чтобы передать ref в вызове функции, вам нужно:

int a = 10;
foo(ref a);

Так что нечто похожее на это в LUA может вызвать ошибки, которые вы показываете.

0 голосов
/ 06 ноября 2009

Вы можете указать SWIG, как преобразовать представление внутреннего указателя в константную ссылку, используя карту типов:

%typemap(in) const Foo&
{
    if(!SWIG_IsOK(SWIG_ConvertPtr(L,$argnum, (void**)$1, $1_descriptor,1)))
    {
         SWIG_fail;
    }
}

Это должно сгенерировать код, который будет выглядеть примерно так в вашем файле wrap.cpp:

if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_Foo,1)))
{
  SWIG_fail;
}
result = new Foo2(((Foo const &)*arg1);
SWIG_arg=0;

SWIG_Lua_NewPointerObj(L, result, SWIGTYPE_p_Foo2, 1); SWIG_arg++;
0 голосов
/ 08 октября 2009

Если вы сделаете интерфейс lua с помощью swig, попробуйте вместо этого:

foo2 (const foo * f) {* this = * f;}

swig имеет некоторые проблемы с ссылочными типами, но делает автоматическое преобразование из указателей без проблем.

Я думаю, что ссылка на const является проблемой в swig здесь

...