views:

515

answers:

5

I don't know why I'm having a hard time with this. All I want to do is this:

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;
*/

The problem I'm having is that, after swigging this code, I can't figure out how to make the lua script play nice.

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

The error I get is "Wrong arguments for overloaded function 'new_Foo2'": Possible c/c++ prototypes are: foo2() foo2(foo const &)

The same thing happens if I try and use do f2 = f. As I understand it everything is stored as a pointer so I did try adding an additional constructor that took a pointer to foo but to no avail.

+1  A: 

In the copy constructor you have the reference operator in the wrong place, put it after 'foo'. As your code stands it doesn't compile, at least not for me on VS 2008.

Edit: I see, thanks for the update. Well I'm not particularily familiar with LUA, but I know when porting from C++ to C# there are a few things that change when it comes to references. So my only idea would be if you need to explicitly show that you are passing a variable by ref/const ref. Ie. in C# to pass by ref in a function call you need:

int a = 10;
foo(ref a);

So something similar to this in LUA might cause the errors you show.

DeusAduro
Ack my bad. I'm at work where they have disabled USB and the code is on my other PC so I was forced to manually retype my example.
+1  A: 

God only knows what SWIG is doing. My advice is to bite the bullet and use Lua's C API, which also works with C++. It's not that hard to learn, and you'll be able to overload the foo2 method exactly the way you want. Good examples can be found in Roberto Ierusalimschy's book Programming in Lua; you can get the previous edition free online.

N.B. Since the API is C, it doesn't know from reference parameters. Your Lua userdata object should contain a pointer to the C++ object of class foo2.

Norman Ramsey
+1  A: 

Along the lines of the suggestion to use Lua's native C API, but since you're in C++, try out Luabind. It works very well once you get the hang of it. If you do try it be sure to get the latest version--it's actively maintained and getting better all the time.

John Zwinck
Thanks, I think this might be the path of least resistance. @Norman's advice above: I started down the road of manually working with Lua's C API but unfortunately the example I provide above is only a very small example of a very large code base that I'd very much like not to wrap by hand.
So how did it work out? If you ended up using Luabind, please consider marking my answer as accepted (the checkmark to its left that should appear on your screen).
John Zwinck
A: 

If you make the lua interface with swig try this instead:

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

swig has some problems with the reference types but make the automatic conversion from pointers without problems.

I think that the const reference is the problem in swig here

Beko
A: 

You can tell SWIG how to convert the internal pointer representation to a const reference using a typemap:

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

This should generate code that looks something like this in your wrap.cpp file:

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++;
Aaron Saarela