how to tell/cast instance of for C++ interfaces from within a C class - c++

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.

Related

Abstract Class/Interface C++

I'm having some difficulty understanding abstract classes/interfaces and I was wondering if someone would be kind enough to help me with my understanding.
It is my understanding that an interface is a means of defining the functionality of an object(how to use it) without defining its implementation.
So for instance, take a TV as an example.
Many manufacturers make TVs. If we were to define an interface for a TV, it may have methods such as :
ChangeChannel,
PowerOn,
PowerOff,
RaiseVolume etc.....
So the interface is the human -> machine interface (buttons, knobs etc) and the implementation is the 'black box' internals we are interfacing with.
So then, if we wrote some classes that inherited from TV such as PhilipsTV, SonyTV etc which defined their own implementations of the methods defined in TV, then those specific manufacturer TV objects would override the TV interface methods and also provide an implementation.
Therefore, if we wanted to pass a TV object to a function but we didn't know which specific manufacturer made the TV until runtime, we could have a function such as :
void doSomethingWithTV(TV telly){
telly.ChangeVolume(10);
}
and call it like so :
void main()
{
SonyTV t = new SonyTV;
doSomethingWithTV(t);
}
The internals of doSomethingWithTV would know what methods a TV has since it is inherits from TV interface, but we may pass in a SonyTV or a PhilipsTV etc at runtime and they would be treated the same.
Unfortunately I'm having great difficulty passing an interface type as a parameter as my compiler says :
cannot declare parameter 'telly' to be of abstract type 'TV' because the following virtual functions are pure within 'TV':
virtual void TV::changeVolume(int)
Please could someone tell me if I'm understanding the term 'interface' correctly and if so how should I direct my research in order that I can learn the nessesary skills to be able to implement a pattern such as I have outlined above.
Thanks in advance, Rick.
"Unfortunately I'm having great difficulty passing an interface type as a parameter as my compiler says : ..."
You cannot pass abstract interfaces by value, so you change
void doSomethingWithTV(TV telly){
telly.ChangeVolume(10);
}
to receive a reference or pointer parameter like this
void doSomethingWithTV(TV& telly);
or
void doSomethingWithTV(TV* telly);
The by value parameter requires you to have instances of TV.
Yeah, that's all right, except for two observations:
main must return int, not void
C++ isn't Java. You can't pass objects of by value around by their interface type and expect polymorphism to work. What you're trying to do is pass a fresh TV object into the function, but that can't work because an interface cannot be instantiated. If you instead pass a reference TV&, const TV& or pointer TV* then this is instead a handle to the original object and, when you use a handle, polymorphism can take hold.
Both of these points are explained in your C++ book, so simply continue to read it to the end.
Yes, you're understanding of what is an interface is pretty clear.
But :
You must use interface types (Tv here) with a pointer.
So in your exemple it would be:
void doSomethingWithTV(TV* telly){
telly->ChangeVolume(10);
}
and
void main()
{
TV* t = new SonyTV;
doSomethingWithTV(t);
}
An interface is made to pass a kind of contract : if you want to inherit from me you must implement all the pure virtual functions that I contain.
It's not meant to be instantiated.
As you said, the function to call will be determined at runtime, so the compiler would not know which code to call at compile time.
This happens because your TV class has a pure virtual function. You can't instantiate a class with a pure virtual function.
Any class with a pure virtual function is an abstract class. These classes can't exist on their own, they need to be derived from by for example a SonyTV. If this SonyTV has defines the pure virtual function, then it would work.
You're doSomethingWithTV() asks for a TV, you're compiler errors because this function can never receive a TV. It can however receive references to a TV or classes derived from TV.
More information:
https://en.wikibooks.org/wiki/C%2B%2B_Programming/Classes/Abstract_Classes
https://en.wikipedia.org/wiki/Virtual_function

C++ Class References

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.

Using c++ object in c

I am writing code in c++. I need to support few basic data types and something like BigInt. This types will be exposed to outside world(through header file), which might also include c program.
Should I implement BigInt like data type as struct or class?
The confusion is because
1. If I implement it as class, as OO advantages, I can do all processing in class. But I may have to implement some work around for c programs
2. If I implement it as struct I need not do anything special for c programs, but I loose modularity and ease of implementation.
basically C couldn't access C++ objects, either struct/class (they're the same in C++, only differs in default visibility specifier). You have to create procedural wrapper for the C++ object (i.e. creation, method call, destruction, etc).
For creation, create a function that returns opaque pointer (in C++, this would be the object pointer). For method call, add the returned pointer (from creation function above) as one of the (typically first) parameter. For destruction it's the same as method call, but typically receives no other parameter other than the pointer above.
If you plan on using it in C, I suggest you write it in C. C++ gets along with C a million times better than C gets along with C++. Another option would be to write it in C and then provide a thin C++ wrapper that gives it an OO interface.

c++ library with c interface

i need to write a library in c++ , usable by client to do some operations in a remote server. The only thing in the specific i haven't done yet it's: The c++ library need a C interface. Let me explain better:
From client using this lib i need to do call something like:
int operation(void* addr);
if int<0 error
and so..
But the library it's a class in c++.
So my answer is.. Need I a global variable holding the instance of class in the library?
The are some better option to develop this C interface of C++ class?
Thx in advice for answer.
You can use the PIMPL idiom in the C wrapper. You provide a method YourClass_Create that internally calls the constructor (using new) and returns the pointer to your class instance; for the client code this will be just an opaque handle (it may be a typedef for void *), to be passed to every function of your C interface to specify on which instance it has to work (just like FILE * in stdio).
All these functions will have to do is to call the corresponding method on the handle (converted back to a pointer to your class) and translate exceptions to error codes.
As #jdv-Jan de Vaan pointed out in his comment, don't forget the necessary #ifdefed extern "C" {} around your C wrapper code, otherwise you may get linker errors.

A function expects a C++ object of abstract type A. How do I pass it a Lua object of an A subclass?

I'd like to pass to a function expecting a C++ object of a pure virtual class a Lua object of a class that derives from the pure virtual C++ class. How can I do this?
I'm new to lua and luabind so bear with me.
In C++:
struct A {
virtual void foo() = 0;
};
void do_something(A* a) {
a->foo();
}
In Lua:
class 'MyA' (A)
....
function MyA:foo()
print('hi')
end
In C++ again:
... // somehow create an instance of MyA class and named myA
// How?
// Maybe the result of a call to "MyA()"?
do_something(myA);
You would have to create a C++ class which implements your pure virtual function, then calls the Lua code. The implementation would be too complicated to just throw in here.
Basic pseudo code:
// C++
struct LuaA : public A
{
LuaA(const std::string &luacode)
: myLuaHandler(luacode)
{
}
virtual void foo()
{
myLuaHandler.call("MyA:foo()");
}
}
That example is very high level, but it's meant to show that what you want to do is non-trivial. It's the new "LuaA" that you would want to actually expose to your Lua code.
In general I prefer to use SWIG when wrapping my C++ for exposure to Lua and other scripted languages. SWIG does support this overloading of virtual methods that you are interested in (called "directors" in SWIG parlance), however, it should be noted that Lua/SWIG does not support directors. Java, C#, Ruby, Perl and Python do all have directors support in SWIG. I'm uncertain as to exactly why it is not supported in Lua.
It is possible, that since Lua does not support inheritance, the exact semantics of what you would like to accomplish are simply not possible in the way you propose.
Perhaps someone else has a better answer to the Lua side of things?
See section 10.1 in the LuaBind documentation. You basically provide a simple C++ wrapper to the LuaBind class that acts as a pass through to the underlying Lua implementation. Notice the following from this doc:
virtual void f(int a)
{
call<void>("f", a);
}
call("f", a) will invoke the Lua 'f' function, passing in the argument a.
Sorry, I would not answer the question you've asked directly, but will offer a bit of advice from personal experience instead:
If you're new to Lua, you should seriously consider writing your first bindings in raw Lua API and without such object-oriented layout. At least you will understand what is really going on.
Lua API is quite comfortable to use by itself. It does not create any extra overhead and you're in full control on what is happening. Luabind library development is a bit stale at the moment (but it looks like it comes back to life though).
You should consider if you really need to imitate deriving from C++ classes in Lua-side and, especially, on C++-side. Such thing is not-so-natural for Lua and requires noticeable overhead to be implemented. Furthermore, in C++ you're hiding the fact that you're making a non-native call to another language. Unless well documented, this is a potential source for performance issues.
When I've started working with Lua a few years ago, I've used to write bindings in the same way as you do, with Luabind, and imitating deriving from C++ objects. Now I'm using pure Lua API and simplistic procedural (as opposed to object-oriented) cross-language interface. I'm a lot happier with the result.
I will subclass the pure virtual class in C++ and then likely start with luabind (as per Aaron and lefticus' solutions). If this overhead is too great, I will just use the straight Lua C stack-twiddling API (as per Alexander).
Thus, there's no one answer here. I will post a comments with results later.
Thanks everyone!