Класс Swig C++ Lua Pass по ссылке

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

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/С++: foo2() foo2(foo const &)

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


person Community    schedule 07.08.2009    source источник


Ответы (5)


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

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

int a = 10;
foo(ref a);

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

person DeusAduro    schedule 07.08.2009
comment
Признай, мой плохой. Я на работе, где они отключили USB, а код находится на моем другом компьютере, поэтому мне пришлось вручную перепечатать мой пример. - person ; 07.08.2009

Одному Богу известно, чем занимается SWIG. Мой совет — стиснуть зубы и использовать C API Lua, который также работает с С++. Этому не так сложно научиться, и вы сможете перегружать метод foo2 именно так, как вам нужно. Хорошие примеры можно найти в книге Роберто Иерусалимского Programming in Lua; вы можете получить предыдущую версию бесплатно в Интернете.

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

person Norman Ramsey    schedule 07.08.2009

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

person John Zwinck    schedule 08.08.2009
comment
Спасибо, я думаю, что это может быть путь наименьшего сопротивления. Совет @Norman выше: я начал с ручной работы с C API Lua, но, к сожалению, приведенный выше пример является лишь очень маленьким примером очень большой базы кода, которую я очень не хотел бы оборачивать вручную. - person ; 11.08.2009
comment
Итак, как это сработало? Если вы в конечном итоге использовали Luabind, рассмотрите возможность пометить мой ответ как принятый (галочка слева от него, которая должна появиться на вашем экране). - person John Zwinck; 16.09.2009

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

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

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

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

person Community    schedule 08.10.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++;
person Aaron Saarela    schedule 06.11.2009