Would it be possible using Lua and SWIG and say an IInterface class, to implement that interface and instantiate it all within Lua? If so how would it be done?
In the first place, C++ style interfaces does now make much sense in a language like Lua. For a Lua object to conform to an interface, it just need to contain definitions for all the functions in that interface. There is no need for any specific inheritance. For instance, if you have a C++ interface like this:
// Represents a generic bank account
class Account {
virtual void deposit(double amount) = 0;
};
you can implement it in Lua without any specific inheritance specifications:
SavingsAccount = { balance = 0 }
SavingsAccount.deposit = function(amount)
SavingsAccount.balance = SavingsAccount.balance + amount
end
-- Usage
a = SavingsAccount
a.balance = 100
a.deposit(1000)
In short, you don't need the C++ interface. If you need to extend the functionality of a C++ class from Lua, you should wrap that into a Lua object as described here and do "metatable" inheritance as explained here. Also read the section on Object Oriented Programming in the Lua manual.
Store the table in a c++ class by holding a pointer to the lua state, and the reference returned for the table as specified using this API:
http://www.lua.org/pil/27.3.2.html
Then when a method on the wrapper class is called, push the referenced object onto the stack and do the necessary function call
Related
Coming from Delphi, I'm used to using class references (metaclasses) like this:
type
TClass = class of TForm;
var
x: TClass;
f: TForm;
begin
x := TForm;
f := x.Create();
f.ShowModal();
f.Free;
end;
Actually, every class X derived from TObject have a method called ClassType that returns a TClass that can be used to create instances of X.
Is there anything like that in C++?
Metaclasses do not exist in C++. Part of why is because metaclasses require virtual constructors and most-derived-to-base creation order, which are two things C++ does not have, but Delphi does.
However, in C++Builder specifically, there is limited support for Delphi metaclasses. The C++ compiler has a __classid() and __typeinfo() extension for retrieving a Delphi-compatible TMetaClass* pointer for any class derived from TObject. That pointer can be passed as-is to Delphi code (you can use Delphi .pas files in a C++Builder project).
The TApplication::CreateForm() method is implemented in Delphi and has a TMetaClass* parameter in C++ (despite its name, it can actually instantiate any class that derives from TComponent, if you do not mind the TApplication object being assigned as the Owner), for example:
TForm *f;
Application->CreateForm(__classid(TForm), &f);
f->ShowModal();
delete f;
Or you can write your own custom Delphi code if you need more control over the constructor call:
unit CreateAFormUnit;
interface
uses
Classes, Forms;
function CreateAForm(AClass: TFormClass; AOwner: TComponent): TForm;
implementation
function CreateAForm(AClass: TFormClass; AOwner: TComponent): TForm;
begin
Result := AClass.Create(AOwner);
end;
end.
#include "CreateAFormUnit.hpp"
TForm *f = CreateAForm(__classid(TForm), SomeOwner);
f->ShowModal();
delete f;
Apparently modern Delphi supports metaclasses in much the same way as original Smalltalk.
There is nothing like that in C++.
One main problem with emulating that feature in C++, having run-time dynamic assignment of values that represent type, and being able to create instances from such values, is that in C++ it's necessary to statically know the constructors of a type in order to instantiate.
Probably you can achieve much of the same high-level goal by using C++ static polymorphism, which includes function overloading and the template mechanism, instead of extreme runtime polymorphism with metaclasses.
However, one way to emulate the effect with C++, is to use cloneable exemplar-objects, and/or almost the same idea, polymorphic object factory objects. The former is quite unusual, the latter can be encountered now and then (mostly the difference is where the parameterization occurs: with the examplar-object it's that object's state, while with the object factory it's arguments to the creation function). Personally I would stay away from that, because C++ is designed for static typing, and this idea is about cajoling C++ into emulating a language with very different characteristics and programming style etc.
Type information does not exist at runtime with C++. (Except when enabling RTTI but it is still different than what you need)
A common idiom is to create a virtual clone() method that obviously clones the object which is usually in some prototypical state. It is similar to a constructor, but the concrete type is resolved at runtime.
class Object
{
public:
virtual Object* clone() const = 0;
};
If you don't mind spending some time examining foreign sources, you can take a look at how a project does it: https://github.com/rheit/zdoom/blob/master/src/dobjtype.h (note: this is a quite big and evolving source port of Doom, so be advised even just reading will take quite some time). Look at PClass and related types. I don't know what is done here exactly, but from my limited knowledge they construct a structure with necessary metatable for each class and use some preprocessor magic in form of defines for readability (or something else). Their approach allows seamlessly create usual C++ classes, but adds support for PClass::FindClass("SomeClass") to get the class reference and use that as needed, for example to create an instance of the class. It also can check inheritance, create new classes on the fly and replace classes by others, i. e. you can replace CDoesntWorksUnderWinXP by CWorksEverywhere (as an example, they use it differently of course). I had a quick research back then, their approach isn't exceptional, it was explained on some sites but since I had only so much interest I don't remember details.
I'm aware that the windows "directshow" headers have both C++ class definitions, as well as their "C" struct equivalents.
My question is, if I call into a C++ method (from C--ffmpeg in this case) and it returns me a class, how can I determine if the object passed to me passes the "is a" test for various interfaces? How can I cast it to its various interface methods? If that makes sense. (all from in straight C).
The example in question is, given ffmpeg's dshow layer: https://github.com/FFmpeg/FFmpeg/tree/master/libavdevice I have access to IPin's, now I want to cast them to IAMBufferNegotiation (if they implement that interface) like in this example: http://sid6581.wordpress.com/2006/10/09/minimizing-audio-capture-latency-in-directshow/
Thanks!
Basically, I wouldn't. What I'd do is write an adapter layer in C++ that provides a C friendly interface to the C++ framework.
If you are dealing with COM objects, then you can use QueryInterface http://www.codeproject.com/Articles/13601/COM-in-plain-C
In C++, you can attempt a dynamic cast. Let's consider a function animalAtRandom() which returns a pointer to an instance of the Animal class and you'd like to test whether it is an instance of the Dog class.
Animal *someAnimal = animalAtRandom();
Dog *rex = dynamic_cast<Dog *>(someAnimal);
if (rex == NULL)
{
// this Animal is not a Dog
}
else
{
// yay
}
In pure C, this won't be easy. The C++ compiler does some pointer arithmetic to land you at the right offset, so you're better off writing a C++ helper function instead:
extern "C" Dog *fetchFirstAnimalAsDog()
{
return dynamic_cast<Dog *>(animalAtRandom());
}
In one way I can say its not efficient until C++ provides an interface to transfer data back in a C struct.
Member arrangement inside a class is implementation defined and thus some hack to copy data of members according to some sequence fails.
However in some old hacks if you want to retrieve something like important stuff from public section of class it is suggested to do a memcpy.
memcpy(dest_c_struct,src_c_class_ret_from_function,size_define);
But it wont leave you with anything of progressive nature.
UPDATE:
The example in question is, given ffmpeg's dshow layer:
https://github.com/FFmpeg/FFmpeg/tree/master/libavdevice I have access
to IPin's, now I want to cast them to IAMBufferNegotiation (if they
implement that interface) like in this example:
Are you talking about C ?? Casting IPin interface to IAMBufferNegotiation??
If I am understanding correctly, then its not possible to cast one interface type to another interface in C. In fact there are no interfaces in C.Only way is to switch back to C++ or provide C friendly interface to FFmpeg library with your application.
So, I want to be able to modify already instanced C++ objects in a scripting language. I have been looking at Lua with LuaBind and Python with SWIG or Boost::Python, but all I see is how to make new instances of the objects, but I want to modify already existing ones.
Example:
C++:
Player playerOne = new Player();
Scripting Language :
playerOne.Transform.x += 5;
Is this possible, and if so, wat would you suggest as a good Language/library to achieve this with?
In my main project we use LuaBind, and it works pretty well. We do basically what you're asking to do. We have existing C++ objects where we want behavior extended in various ways, but it would be a lot of work and risky to do those changes in behavior in the C++ code for the object itself.
So in your example, you'd want at least 2 C++ wrapper classes - one that represents the 'Game' that allows you to write an API function to return players, and a wrapper class that wraps the C++ player class that you can return to lua. Each wrapper function would have api functions/properties that would fiddle with the individual object it's wrapped internally that lua could call and pass values to. Here is a link to an article giving you pretty straightforward examples of using LuaBind and what it looks like:
http://blog.nuclex-games.com/tutorials/cxx/luabind-introduction/
I recently needed to do the same thing. I also considered (and used) Boost.Python but personally (as much as I love Boost) I felt it was a little overkill to drag in half the Boost library to get one feature.
So, if you're interested, I recently implemented a very light-weight Python wrapper library called ECS:Python. ECS:Python (Embedded C++ Scripting with Python) is designed specifically for C++ developers that wish to expose objects FROM a C++ application TO an embedded Python interpreter for interactive scripting.
Its free (BSD) and open source: http://sourceforge.net/projects/ecspython
There is no mechanism that can magic values into a scripting language from the host language. If you want a particular object instances to be accessible in the scripting language, it must be given to the scripting language via some function.
This is no different from any other properly encapsulated C++ type. If object A creates and stores some instance T, then the only way object B can get it is if it calls a function on A that returns T.
I was having the problems in my project. Have a look at my post in the Ogre3d forums:
http://www.ogre3d.org/forums/viewtopic.php?f=5&t=41631&p=332200&hilit=mrmclovin#p405204
Code example:
int main (int argc, char * const argv[])
{
try
{
// Initialize the python interpreter
Py_Initialize();
// Create a module dynamically
object module((handle<>(borrowed(PyImport_AddModule("NameOfMyModule")))));
// Retrieve the module's namespace
object main_namespace(module.attr("__dict__"));
// Put a c++ class named "Car" exported using boost.python into our module
main_namespace["Car"] = class_<Car>("Car")
.def("drive", &Car::drive)......;
// The class car now exists in a dynamic module
// and that module is accessable everywhere as longs as the python interpreter exists
// Create a instance of Car here
Car* myCar = new Car(...);
// Now simply add it to the module. Make sure you have exposed class Car before adding instances
main_namespace["car_instance"] = object(ptr(myCar)); // the boost python ptr() class make sure not to copy the pointee but only copy pointer adress
}
catch( error_already_set )
{
PyErr_Print();
}
return 0;
}
Currently I know how to have C++ objects instantiated and passed around in Lua using SWIG bindings, what I need is the reverse.
I am using Lua & C++ & SWIG.
I have interfaces in C++ and objects in lua, that implement methods which do the same job and have the same structure. I would like to be able to instantiate these objects in lua yet pass them around in C++ using pointers to that interface which they resemble.
As such I can imagine creating a c++ implementation of the interface which would act as a handler for said lua object, yet I don't know how to do this. The class would act as the lua objects representative or proxy in the C++ world.
To clarify I shall start with the following example code used in an answer to a similar question I asked:
C++ code:
// Represents a generic bank account
class Account {
virtual void deposit(double amount) = 0;
};
Lua code:
SavingsAccount = { balance = 0 }
SavingsAccount.deposit = function(amount)
SavingsAccount.balance = SavingsAccount.balance + amount
end
-- Usage
a = SavingsAccount
a.balance = 100
a.deposit(1000)
Now say that I have a class in C++ called Bank:
class Bank {
void AddAccount(Account* a);
};
What I would like here is a mechanism for doing the following in lua:
SavingsAccount = { balance = 0 }
SavingsAccount.deposit = function(amount)
SavingsAccount.balance = SavingsAccount.balance + amount
end
-- Usage
a = SavingsAccount
bank:AddAccount(a)
If I need to take an extra step such as instantiating a C++ class to act as a proxy and pass it the lua table with all my lua functions etc, I can imagine it looking like this:
C++ code:
// Represents a generic bank account
class ProxyAccount : public Account {
virtual void deposit(double amount);
};
Lua code:
SavingsAccount = { balance = 0 }
SavingsAccount.deposit = function(amount)
SavingsAccount.balance = SavingsAccount.balance + amount
end
-- Usage
a = SavingsAccount
a.balance = 100
a.deposit(1000)
proxy = program.ProxyAccount()
proxy.settable(a)
bank:AddAccount(p)
The problem here being I have no idea how I would implement the ProxyAccount class, or even what the function signature of settable would look like...
I'm not familiar with SWIG (I know what it is but have never used it) so this may not be the answer you are looking for.
I've been working on a C++ project and have had success using luabind. It allows you to subclass C++ objects with Lua objects. You might want to give it a try and see if it works for you.
What I seem to gather from your examples and the discussions is that you are expecting Lua to be the primary language, and C++ to be the client. The problem is, that the Lua C interface is not designed to work like that, Lua is meant to be the client, and all the hard work is meant to be written in C so that Lua can call it effortlessly.
Now, the important question is: why don't you want to have a C representation of the object, and prefer to have it in Lua? Since C++ is a much lower level language, and object definitions must be static, and Lua dynamically defines its "objects" it is much easier to have Lua adapt to C++ objects.
Another issue I see is that you seem to be designing your Lua code in a very Object Oriented manner. Remember that even though Lua can fake Object Oriented concepts, it is not built as an Object Oriented language, and should not be used primarily as one. If you want a fully OO scripting language, use python instead.
Now if you Really want to do it the other way, and considered that the other alternatives do not work for you, then what I would recommend, is that you keep the Lua object as a coroutine, this will allow you to:
Keep a representation of the object
in C++ (the lua_State *)
Have multiple individual instances of the same "object type"
Lua takes care of the cleanup
However, the downsides are:
All functions that act on an "object"
need to do so through the lua API
There is no easy/fast way to recognize different lua types (you
could use a metatable)
Implementation is quite cumbersome, and hard to decypher.
EDIT:
Here is how you could expose the interface to an object in a script, Each object instance would be running a new lua_State, and run its script individually, thus allowing for your "Object member data" to just be globals inside the script instance. Implementing the API for the object's methods would go like this:
int move(lua_State * L)
{
int idx = lua_getglobal(L, "this");
assert(!lua_isnull(-1));
AIObject * obj = static_cast<AIObject *>(lua_touserdata(L, -1));
lua_pop(1);
//Pop the other parameters
obj->move(/*params*/);
}
You can bind any C function you want to Lua and call it from there. You can define in this function what you expect the contract is between your script and your C++ code. For example, the following would kind of do what you want. You'll need to add meta table information to your Lua tables so you can distinguish different Lua object types.
int lua_AddBankAccount(lua_State* L, int pos)
{
// Assume you've created metadata for your Lua objects.
if (IsAccount(L, pos))
{
// process your 'Account' Lua instance.
}
else
{
// error - tried to add a non-Account.
}
}
You can take this further with SWIG to bind any arbitrary C method, but it's basically the same.
Is there a way to add new methods to a class, without modifying original class definition (i.e. compiled .lib containing class and corresponding .h file) like C#'s class extension methods?
No. C++ has no such capability.
As mentioned in other answers, the common workarounds are:
Define a derived class, perhaps with a factory to hide the actual implementation class
Define a decorator class
Define non-member functions that operate on instances of the class
No, you can't do this in C++.
If you want to achieve something like this you have 2 options,
You could inherit from the class (if this is an option, it might not be legal as the class may not have been written to allow inheritance)
You can write your own wrapper class that has the same interface + your new methods and delegate to the one you want to extend.
I prefer the delegation approach.
C# class extension methods are mostly syntactic sugar. You get the same functionality with free functions (i.e., functions with a reference or constant reference to your class as their first parameter). Since this works well for the STL, why not for your class?
In C++ you can use free functions, but sometimes extension methods work better when you nest many functions together. Take a look at this C# code:
var r = numbers.Where(x => x > 2).Select(x => x * x);
If we to write this in C++ using free function it would look like this:
auto r = select(where(numbers, [](int x) { return x > 2; }), [](int x) { return x * x; });
Not only is this difficult to read, but it is difficult to write. The common way to solve this is to create what is called a pipable function. These functions are created by overloading the | pipe operator(which is just really the or operator). So the code above could be written like this:
auto r = numbers | where([](int x) { return x > 2; }) | select([](int x) { return x * x; });
Which is much easier to read and write. Many libraries use pipable function for ranges, but it could be expanded to other classes as well. Boost uses it in their range library, pstade oven uses it, and also this C++ linq library uses it as well.
If you would like to write your own pipable function, boost explain how to do that here. Other libraries, however, provide function adaptors to make it easier. Pstade egg has a pipable adaptor, and linq provides the range_extension adaptor to create a pipable function for ranges as least.
Using linq, you first just create your function as a function object like this:
struct contains_t
{
template<class Range, class T>
bool operator()(Range && r, T && x) const
{ return (r | linq::find(x)) != boost::end(r); };
};
Then you initialize the function using static initialization like this:
range_extension<contains_t> contains = {};
Then you can use your pipable function like this:
if (numbers | contains(5)) printf("We have a 5");
Generally not. However, if the library does not create instances of the class that require your extension and you are able to modify all places in the app that create an instance of the class and require your extensions, there is a way you can go:
Create a factory function that is called at all places that require an instance of the class and returns a pointer to the instance (google for Design Patterns Factory, ...).
Create a derived class with the extensions you want.
Make the factory function return your derived class instead of the original class.
Example:
class derivedClass: public originalClass { /* ... */};
originalClass* createOriginalClassInstance()
{
return new derivedClass();
}
Whenever you need to access the extensions, you need to cast the original cast to the derived class, of course.
This is roughly how to implement the "inherit" method suggested by Glen. Glen's "wrapper class with same interface" method is also very nice from a theoretical point of view, but has slightly different properties that makes it less probable to work in your case.
There is one way in which it can be done. And that's by relaxing your requirements a bit. In C++, people often say that the interface of a class consists not just of its member functions, but of all functions that work on the class.
That is, non-member functions which can be given the class as a parameter should be considered part of its interface.
For example, std::find() or std::sort() are part of the interface of std::vector, even though they aren't members of the class.
And if you accept this definition, then you can always extend a class simply by adding nonmember functions.
You cannot add methods or data physically to the class file which is in binary form. However, you can add methods and data (functionality and state) to the objects of that class by writing extension classes. This is not straight forward and requires Meta-Object-Protocol and Interface based programming. You need to do a lot to achieve this in C++ since it does not support Reflection out of the box. In such an implementation when you query for the interface implemented by your new extension class via the original class object pointer, the meta object implementation returns that interface pointer via the meta class object for the extension class that it creates at runtime.
This is how many customizable (plugin based) software application frameworks work. However, you must remember that it requires many other MOP mechanisms to be written to instanciate meta objects for all the classes using dictionaries in which the object relations are described and give the correct interface pointers for the original and extended class objects. Dassault Systemes' CATIA V5 is written in such an architecture called CAA V5 where you can extend existing components by writing new extension classes with the desired functionality.
Sure you can:
template <typename Ext>
class Class: public Ext { /* ... */ };
That doesn't mean it's the best approach though.
Sorry, no. Once your code is in obj, you can not change it. If this can be done in VC partial classes would be supported already. There is one exception though, operator methods can be extended using global functions, pretty like how cout<< is implemented in STL.