VS2010 C++ - problem casing based class pointer to derived class pointer - c++

Using VS2010 and C++, I am using a supplier library to interface to their USB industrial camera.
The library has an base abstract class for data stream sinks called GrabberSinkType, and one of derived classes from that is MediaStreamSink which deals with writing streams to video files. One of the methods supported by MediaStreamSink (not a virtual function of the base class) is getFilename() which simply returns the name of the file being written to.
The main Grabber class which handles streaming has a method getSinkTypePtr(), which returns a pointer to the sink in current use, defined as smart_ptr<GrabberSinkType> getSinkTypePtr() const;.
What I need to do is check if is a MediaStreamSink, and if so, get the filename. And I cannot get it to compile. Having checked if it is a media stream type, all I am doing is
CString SinkPath = dynamic_cast<tMediaStreamSinkPtr>(m_cGrabber.getSinkTypePtr())->getFilename().c_str();
(tMediaStreamSinkPtr is typedef'd assmart_ptr<MediaStreamSink>). This results in error 2680:
"error C2680: 'DShowLib::tMediaStreamSinkPtr' : invalid target type for dynamic_cast
target type must be a pointer or reference to a defined class"
I have tried every possible combination of dynamic casts, static casts, old style casts I can think of, and whilst the error changes, I cannot get it to compile.
I clearly don't know what I'm doing here, how do I get a pointer to the dervied class and successfully call its getFilename() method?

Related

Passing C++/CLI object pointer to a native object method

I am having some trouble passing a C++/CLI object pointer to a native object.
The entire picture is the following:
I am new to C++ in general (doomed)
I am using a third party native C++ library to interface a blackmagic IO video card. In the API there is a very handy method to pass a pointer of the object that will handle the frame callback while they are captured by the card:
SetCallback(Pointer to an object that implement an interface).
In the above SetCallback(Pointer) I would like to pass the pointer to my C++/CLI object. When I do so
I get: cannot convert argument 4 from 'CLIInterop::Wrapper ^*' to 'IDeckLinkInputCallback *'
My final target is to handle the callback from C++ into C++/CLI and at this point pass the frame over to WPF (if I will ever get that far)
The line of code invoved are:
Call from CLIInterop::Wrapper object
d_Controller->GetDevice()->StartCapture(0, nullptr, true, this);
Method header in the native C++ project:
__declspec(dllexport) bool DeckLinkDevice::StartCapture(unsigned int videoModeIndex, IDeckLinkScreenPreviewCallback* screenPreviewCallback, bool applyDetectedInputMode, IDeckLinkInputCallback* callbackHandler);
Help!
It is clearly indicate that your this pointer is not a type IDeckLinkInputCallback
d_Controller->GetDevice()->StartCapture(0, nullptr, true, this);
^ this pointer is not a type IDeckLinkInputCallback
As you told that you have already implement interface IDeckLinkInputCallback in the class of this pointer. Double check whether you have done it. Instead of calling StartCapture from the member function of the class better call it from outside and provide full address of the object instead this pointer.
You cannot just pass a managed reference ("hat pointer" ^) when a native pointer is expected. The whole point of C++/CLI is the possibility to create "glue" code such as what you're missing.
Basically, you would have to create a native class that implements the native interface, which may contain the managed reference that you call back to. I'm not familiar with the BlackMagic video card's interface (I used to have to work with DVS video cards, but their software interfaces are probably hardly comparable), but the general logic for such a wrapper would be similar to this:
class MyDeckLinkInputCallback : IDeckLinkInputCallback
{
public:
MyDeckLinkInputCallback(CLIInterop::Wrapper^ wrapper)
{
_wrapper = wrapper;
// initialize to your heart's content
}
private:
CLIInterop::Wrapper^ _wrapper;
public:
// TODO implement IDeckLinkInputCallback properly; this is just a crude example
void HandleFrame(void* frameData)
{
// TODO convert native arguments to managed equivalents
_wrapper->HandleFrame(...); // call managed method with converted arguments
}
};

c++ plugin : Is it ok to pass polymorphic objects?

When using dynamic libraries, I understand that we should only pass Plain Old Data-structures across boundaries. So can we pass a pointer to base ?
My idea is that the application and the library could both be aware of a common Interface (pure virtual method, = 0).
The library could instantiate a subtype of that Interface,
And the application could use it.
For instance, is the following snippet safe ?
// file interface.h
class IPrinter{
virtual void print(std::string str) = 0;
};
-
// file main.cpp
int main(){
//load plugin...
IPrinter* printer = plugin_get_printer();
printer->print( std::string{"hello"} );
}
-
// file plugin.cpp (compiled by another compiler)
IPrinter* plugin_get_printer(){
return new PrinterImpl{};
}
This snippet is not safe:
the two sides of your DLL boundaries do not use the same compiler. This means that the name mangling (for function names) and the vtable layout (for virtual functions) might not be the same (implementation specific.
the heap on both sides may also be managed differently, thus you have risks related to the deleting of your object if it's not done in the DLL.
This article presents very well the main challenges with binary compatible interfaces.
You may however pass to the other side of the mirror a pointer, as part of a POD as long as the other part doesn't us it by iself (f.ex: your app passes a pointer to a configuration object to the DLL. Later another DLL funct returns that pointer to your app. Your app can then use it as expected (at least if it wasn't a pointer to a local object that no longer exists) .
The presence of virtual functions in your class means that your class is going to have a vtable, and different compilers implement vtables differently.
So, if you use classes with virtual methods across DLL calls where the compiler used on the other side is different from the compiler that you are using, the result is likely to be spectacular crashes.
In your case, the PrinterImpl created by the DLL will have a vtable constructed in a certain way, but the printer->print() call in your main() will attempt to interpret the vtable of IPrinter in a different way in order to resolve the print() method call.

How to drag/drop both file and text in same window in wxWidgets?

I'm working on a program that needs to open images from both local disk and internet. WxWidgets provides wxFileDropTarget and wxTextDropTarget, but each class can only support one type of data object (wxFileDataObject and wxTextDataObject). I've try to derive class from two base classes, but the compiler says ambiguous conversions from 'CMyDropTarget *' to 'wxDropTarget *'. How can I create a window accept two data type?
As far as I know, the simplest solution is to use a wxDataObjectComposite, to which you Add() both a wxFileDataObject and a wxTextDataObject.
You derive your own class from wxDropTarget, override its pure virtual OnData(), and call its SetDataObject() with the appropriately constructed wxDataObjectComposite in your derived class' constructor.
There's a pretty good example of it all in the docs for wxDataObjectComposite. It gives you an overview of what needs to be done, just keep in mind that there are a few details that I think are not quite right in there:
The call to wxDropTarget::OnData() won't work, as that's a pure virtual (you shouldn't call it at all in my opinion).
You should, however, call GetData() instead, to populate the wxDataObjectComposite with the preferred data format (or another one that is available), and test its return value.
dataObjects->GetReceivedFormat() should be dataobjComp->GetReceivedFormat().

COM: Getting GUID of coclass object using pointer to interface it implements

Having pointer to COM interface that are implemented by some concrete component class object is it possible to get a GUID of the underlying object that implements this interface (CLSID)?
Update 1
More generally, I have a function like SetFont(ICanvasFont* font) and I need a way to determine if the underlying object that implements the ICanvasFont interface is of a certain class (say MCanvasFont).
IUnknown::QueryInterface on this interface pointer to obtain one of the following: IPersist, IPersistStream, IPersistStreamInit or other IPersist* interfaces. If you are lucky to get one, then GetClassID method will get you the CLSID class identifier (alternate option is IProvideClassInfo and IProvideClassInfo::GetClassInfo).
Note that this kind of information does not have to exist. An interface pointer can be valid without having CLSID on the class implementing it.
UPD. If the main goal is to recognize your own implementation on the provided interface ("Is the provided ICanvasFont the instance of my own MCanvasFont class, or it is something different?"), then the easiest yet efficient way is to implement some extra private interface on the class. If your querying it succeeds, then you recognize the instance. Provided no marshaling takes place, you can possibly even static_cast back to original C++ pointer.

Is there a way to determine at runtime if an object can do a method in C++?

In Perl, there is a UNIVERSAL::can method you can call on any class or object to determine if it's able to do something:
sub FooBar::foo {}
print "Yup!\n" if FooBar->can('foo'); #prints "Yup!"
Say I have a base class pointer in C++ that can be any of a number of different derived classes, is there an easy way to accomplish something similar to this? I don't want to have to touch anything in the other derived classes, I can only change the area in the base class that calls the function, and the one derived class that supports it.
EDIT: Wait, this is obvious now (nevermind the question), I could just implement it in the base that returns a number representing UNIMPLEMENTED, then check that the return is not this when you call it. I'm not sure why I was thinking of things in such a complicated manner.
I was also thinking I would derive my class from another one that implemented foo then see if a dynamic cast to this class worked or not.
If you have a pointer or reference to a base class, you can use dynamic_cast to see which derived class it is (and therefore which derived class's methods it supports).
If you can add methods to the base class, you can add a virtual bool can_foo() {return false;} and override it in the subclass that has foo to return true.
C++ does not have built in run-time reflection. You are perfectly free to build your own reflection implementation into your class hierarchy. This usually involves a static map that gets populated with a list of names and functions. You have to manually register each function you want available, and have consistency as to the calling convention and function signature.
I believe the most-correct way would be to use the typeid<> operator and get a reference to the type_info object, and then you could compare that (== operator) to the desired type_info for the data types you wish to care about.
This doesn't give you method-level inspection, and does require that you've built with RTTI enabled (I believe that using typeid<> on an object that was built without RTTI results with "undefined" behavior), but there you are.
MSDN has an online reference to get you started : http://msdn.microsoft.com/en-us/library/b2ay8610%28VS.80%29.aspx