Sei sulla pagina 1di 60

LUA BINDING TO C++

ANOTHER ODE TO JOHN


EDWARDS

Randy Gaul
Reflection
 Binding Lua to C++ is a chore
 Functions and objects
 Reflection automates a lot of boilerplate
 Much of this talk is about reflection
Prerequisites
 Here are some must-haves in order to accomplish
Lua binding like I have set up:
 MetaData type info object
 Lookup by string
 RefVariant

 Can use alloca


 Avoids heap memory!!!
 Or use equivalent custom stack allocator
MetaData Information
 Types of required information:
 Name

 Size

 To/From Lua func registration


 For custom to/from routines
 Can also:
 Call new, placement new, delete in a generic way
 See Sean Middleditche’s Lectures
 My website: randygaul.net
RefVariant
 Contains void pointer and MetaData information
 Can typecast void pointer to type with template
cast function
 References some memory by pointer
 Rather efficient an object
 References:
My blog: randygaul.net
Binding Functions
 90% of Lua binding is the binding of C++ functions
 Function binding requires C++ reflection of
functions
 This gets complex due to member functions
 Can also be const
 Void and non-void return values
Binding Functions
 Start with function signature
 Collection of MetaData instances
 Describes argument and return type
 Templating and overloads
 Holds type info
 Does not hold callable pointer
 Type info for:
 Assertions, safety, can be enumerated at run-time
FunctionSignature
 Context is type of this pointer
 Important to support member function
FunctionSignature
 Templated constructor, but not a template type
 Take pointer as template type
 Use static const array of MetaData instances
FunctionSignature
 Will require more overloads for the following:
 Non void return
 Use another template parameter for return type
 Member pointer
 Const
 Void/non void return
 Lots of overloads
 My FunctionSignature is about 1k lines total
FunctionSignature
 Example of member function syntax with return
value and const
FunctionSignature - Checkpoint
 Now can describe any function in C++ with:
 Argument types
 This pointer type
 Return value
 Argument count
 Name
 Useful for:
 Run-time type enumeration
 What was type of fifth param, does it match so and so?
 Type safety
 Questions?
VariantFunction
 Contains the following:
 FunctionSignature

 Actual function pointer


 Special call helper

 Single RefVariant for this pointer

 Goal:
 Call any function with call operator
 Essential for generic code (Lua bindings)
VariantFunction – Actual Fn Ptr
 Actual function pointer can be large
 Up to like 20+ bytes on some compilers
 Why so large?
 Multiple inheritance + vtables
 Use a strange union to contain pointer
 Let compiler deal with actual max bounded size
VariantFunction – Actual Fn Ptr
 Strange Union
VariantFunction – Actual Fn Ptr
 Stranger contents
 Thanks to Treb Connell for providing this
 Not sure where he got it, maybe Boost
VariantFunction – Call Helper
 Clever trick for calling the function pointer
 Store pointer to helper
 Helper is template
 Template parameter is function pointer to call
 This preserves the function pointer type
 Acts as layer of indirection
 Will likely get compiled away
VariantFunction – Call Helper
 Templated call helper
 Upon construction of VariantFunction
 Store pointer to template instance of this
VariantFunction – Call Helper
 Pass in:
 Binding
 This pointer as RefVariant
 Return RefVariant
 Copy return value to here
 Return value likely to require heap memory

 Array of RefVariants
 Allocate these on stack, alloca
 To pass in arguments

 MultiFnPtr union
VariantFunction – Call Helper
 You will need many call helpers
 One per argument count
 Template overloads, le sigh
 Both member function and global functions
 Const/non const member funcs
 Void/non void
 If you’re fancy you can try MS demo compiler
 Variadic templates, no overloads required
 It’s a demo compiler though…
VariantFunction – Call Helper
 One last cavaet
 Callingmember function pointer
 ptr->*Call( params );

 Macro to help:

 Used like:
VariantFunction – Call Helper
 Example of CALL_PTR in action:
VariantFunction - Checkpoint
 Signature
 Argument types
 This pointer type

 Return value

 VariantFunction
 Actual function pointer
 Call helper to store function as template param

 Binding for this pointer


VariantFunction
 Using one to call a function
 Ideal syntax:

 Have to deal with return values


 First param RefVariant reference
 VariantFunction stores return value here

 Call now looks like:


VariantFunction – Return Values
 My own solution:
 Two sets of overloads on call operator
 One set has RefVariant first param
 Has a return value
 One set has just templated types
 Void return
 Downsides:
 Lotsof overloads to write
 User has to remember RefVariant for return value
Questions?
 Topics covered so far:
 MetaData

 RefVariant

 FunctionSignature

 VariantFunction
Lua Primer – A quick and dirty one
 Lua is embedded
 Bunch of C code
 Communicate with Lua by a stack
 Defaulted to max 20 element size
 Not thread-safe!
Lua Primer – A quick and dirty one
 Lua Stack
 Push things onto stack
 Pop things from stack

 Lua can access things on stack


 C++ can access things on stack
 All communication through stack
Lua Primer – A quick and dirty one
 Calling a Lua Function
 Function retrieves args from stack
 Returning pushes values onto stack
 Can return multiple items!
 This means:
 Binding to Lua involves to/from Lua stack operations
Lua Primer – A quick and dirty one
 Lua can only call this signature:

 Our job is to make this:


Lua call C++ Function
 Two options:
 Read 300 page book
 These slides
 Hopefully second option will
will work!

 Really will have to read the book at some point


anyway though
Lua call C++ Function
 Lets hit the ground running:
 Call GenericFunc from Lua

 Pass appropriate VariantFunction to GenericFunc


 Contains the C++ fn to call
 Pop arguments off Lua stack
 Pass args to VariantFunction
 Push return value onto stack
 Done
Lua call C++ Function – Step by Step

 Pass appropriate VariantFunction to GenericFunc


 Best done by upvalue
 Upvalue in Lua – Equivalent to static variables in C
functions
 To call C function from Lua you:
 SetC function as global in Lua environment
 Give the global a name

 Can assign upvalues

 Each upvalue is pointer to VariantFunction


Lua call C++ Function – Step by Step

 Retrieving upvalue:

 Upvalue index – Grab a particular upvalue


 In this case there’s only one upvalue
Lua call C++ Function – Step by Step

 Pop arguments off Lua stack


 Make heavy use of the FunctionSignature!
 Can study code later
Lua call C++ Function – Step by Step

 Pass args to VariantFunction:


Lua call C++ Function – Step by Step

 Push return value onto stack


 First allocate space for return value

 Next push onto Lua stack


Lua call C++ Function - Checkpoint
 Call any C++ function from Lua
 Can pass in args
 Can return value to Lua

 Any questions?
MetaData Magic
 You may have noticed some black boxes…

 These call functions held within MetaData


instances
MetaData Magic
 Recall:
 RefVariant – Contains void * and MetaData instance
 Void* points to some data
 MetaData instance describes that data

 MetaData instance has functions within it


 Each function is defaulted
 User can override default upon type registration
MetaData Magic – My header
 http://pastebin.com/unVFsq60
 Highlights:
MetaData Magic
 Custom to/from for built in types
 Register these to/from
MetaData Magic
 Int to/from Lua
MetaData Magic
 Float to/from Lua
Generic To/From Lua
 Two types of values:
 Reference values
 Pointer
 Object values
 Actual object taking up memory
 Object values in Lua
 Usually comprised of Tables
 Can be more complex
 I don’t even support, except for Vector
 Reference values in Lua
 Pointer to some C++ memory
Generic To/From Lua
 User defined type registration:

 What do?
 Everyone that uses reflection now needs to know Lua
 Bad.
Generic To/From Lua
 Require generic to/from default
 Canbe overridden if user does know Lua!
 Good example is custom vector binding

 I introduce the LuaReference:


Generic To/From Lua
 LuaReference really just a RefVariant
 Generic ToLua turns out to be small

 More on metatable later…


Generic To/From Lua
 Generic FromLua smaller
Generic To/From Lua
 Really we are just passing a RefVariant into Lua,
and then getting it back later
 Warning:
 RefVariant
holds void * to C++ memory
 What happens if that memory is deleted?
Generic To/From Lua - Checkpoint
 Cleared up To/From Lua black box
 Can write simple To/From routines for built in
types
 Generic to/from Lua routine
 Can override default generic to/from if needed
 Questions?
Generic To/From Lua - Improvements

 Ideally can pass reference/value to Lua separately

 As stated before, this is harder


I haven’t even done this myself
Call a Lua Function from C++
 Extremely useful
 Imagine all your AI code in C++ was this:

 Now all gameplay code is in Lua


Call a Lua Function from C++
 Advantages
 Can write code like:
 Lua can hotswap
 AI
 Level behavior
 More..?

 No recompile needed when changed


 Easier to write than C or C++

 Lua is cool
Call a Lua Function from C++
 Will require more overloads…
Call a Lua Function from C++
 Can study code after
Checkpoint
 VariantFunction
 Call any C++ function within C++
 Lua binding
 Call C++ from Lua
 Pass objects to/from Lua

 Call Lua from C++


Improvements
 Error checking!
 You have MetaData, type check EVERYWHERE
 Lack of type checking is EVIL

 Lua error messaging


 You must relay errors out of Lua yourself

 Alloca – no heap allocations ever!


Fin
Resources
 Video talk by John Edwards
 Too big to fit on moodle, can email to request it
 R.gaul@digipen.edu

Potrebbero piacerti anche