5

All the googling I've done so far has turned up things that are very close but just aren't quite cutting it for what I'm trying to do.

Let me describe this in the most basic way possible:

  • Imagine you have a C++ class

    class A
    {
    public:
        int Method();
        int Variable;
    };
    
  • Now imagine you instantiate A* Foo;

  • Now imagine you have a .lua file with this 3 line function:

    function Test()
        local n = Foo:Method();
        Foo.Variable = 0;
        local m = Foo.Variable;
    end
    

How can you bind the object A* to lua such that all those things are doable?

Pseudocode-wise, my first attempt went like this, partly from copy pasting examples:

  1. In a function only called once, regardless of the number of instances of A:
    • create newmetatable( MT )
    • pushvalue( -1 ) (i dont really get this)
    • setfield( -2, "__index" )
    • pushcfunction with a static version of Method that unpacks the A* pointer from checkudata
    • setfield( -2, "Method" )
  2. In an init function called for each instance, e.g. Foo:
    • create a pointer to Foo with newuserdata
    • setmetatable( MT )
    • setglobal with Foo to make the name available to lua
  3. In a test function in main:
    • pcall a test function with the 3 lines of .lua mentioned above, by global name

When doing this, Foo:Hide(); successfully called my static function, which successfully unpacked the pointer and called its member Hide().

So far so good for :Method().

Then I tried to support the .Variable access. Everyone seemed to be saying to use metatables again this time overriding __index and __newindex and make them a sort of generic Get/Set, where you support certain keys as valid variable links e.g. if( key == "Variable" ) Variable = val;

This also worked fine.

The problem is trying to put those two things together. As soon as you override __index/__newindex with a getter/setter that works on Variable, the Method() call no longer calls the Method() static function, but goes into the __index function you bound instead.

All of that said, how does one support this seemingly basic combination of use cases?

Actual code snippets would be much more appreciated than purely theoretical chatter.

Reminder: please respond using the basic C API only, not third party stuff.

relaxok
  • 141
  • 8
  • Lua doesn't have a C++ API, you have to use the C API from C++ – Puppy May 22 '14 at 11:25
  • 4
    *please respond using the basic C API only, not third party stuff.* - then you're screwed. Literally and utterly. Exposing C++ objects to Lua is **extremely complicated**, and if you don't want to use external libraries, you're doomed to reimplement them. – Bartek Banachewicz May 22 '14 at 11:25
  • All of which the OP declined to use. – Puppy May 22 '14 at 11:25
  • @Lightness: Nope. He's clearly coding in C++. – Puppy May 22 '14 at 11:27
  • 3
    Then I shall simply say this: he _should_ be using a C++ wrapper. – Lightness Races in Orbit May 22 '14 at 11:28
  • don't constrain yourself with not using wrappers, as you'll be either reimplementing wrapper libraries, or you'll be solving the problem at the [wrong level of abstraction](http://blog.codinghorror.com/the-wrong-level-of-abstraction/) – Dmitry Ledentsov May 22 '14 at 11:56
  • As I tried to make clear, I'm not interested in the final result - obviously i'd just use luabind or something if that were the case. I'm interested in how you use the C API to achieve the above results, thus the question. – relaxok May 22 '14 at 11:59
  • @relaxok Look into my wrapper, how I did it: https://code.google.com/p/lualite/ . Or look into some other project. Write your own wrapper perhaps. – user1095108 May 22 '14 at 12:20
  • Your question "How can you bind the object A* to lua such that all those things are doable?" implies an answer using wrapper libraries. For the rest, you can take a look at the [Programming in Lua](http://www.lua.org/pil/28.html) book. Who is "everyone", by the way? – Dmitry Ledentsov May 22 '14 at 13:17
  • @DmitryLedentsov the question very clearly states 'with the C Lua API' . As for 'Everyone', people who were writing tutorials/blog posts about binding C++ class member variables to lua - when I googled it. I have read the PiL sections but they're very, very basic and don't address the problem I raised. – relaxok May 22 '14 at 19:37

1 Answers1

0

the Method() call no longer calls the Method() static function, but goes into the __index function you bound instead.

So program it so that if the key exists in the table, return that first, else go for getter/setter.

Puppy
  • 144,682
  • 38
  • 256
  • 465