• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 490
  • Last Modified:

Why am I getting a Unable to cast object of type 'System.__ComObject' when testing a CLI/CPP library with a managed .Net client in Microsoft VS 2013?

Hi:

I've got a CLI/CPP wrapper library which wraps a native C++ library.
The native library completes some of it's processing asynchronously on separate threads.
That wrapper is then available to be consumed by .Net (managed) clients.

I'm trying to write a series of unit tests to test the CLI/CPP layer.
I'm using the default "Microsoft Test" which is available with Visual Studio 2013.
I also have a Console Test application which completes the same basic functionality.

When running my tests, I get the following error:
An unhandled exception of type 'MyNameSpace.MyException' occurred in my-wrapper-cli.dll
Additional information: Unable to cast object of type 'System.__ComObject' to type 'MYNameSpace.Frame'.
// frame is an unmanaged object
UnmanagedFrame frame;

// Create a handle to a "managed" Frame - based on unmanaged one
MYNameSpace::Frame^ imageFrame = gcnew MyNameSpace::Frame(frame);

// Call back to the .Net/Managed client with a handle to the managed object
CallBackToManagedClient(imageFrame);

Open in new window


The code throws the exception on the callback routine.

As I previously stated, the above code snippet works when I'm not processing through the test frame work.
I've tried using NUnit along with the VS NUnit adapter, but I still get the same results

Are there known issues using Microsoft's Test to test asynchronous/multi-threaded CLI/CPP libraries?
Is there a compiler switch I'm missing somewhere?

Should I just base my unit test on a console app to remove the reliance on UnitTestFramework?

Thanks,
JohnB
0
jxbma
Asked:
jxbma
  • 3
  • 2
1 Solution
 
sarabandeCommented:
I would guess that passing handles of managed objects to an unmanaged callback function is not a good idea.

you probably should pass marshaled data to c++ library (which contains all necessary information from the image frame) rather than to rely on that the gc would not destroy the managed object in the meantime (what most likely is the cause for the exception).

Sara
0
 
jxbmaSoftware ConsultantAuthor Commented:
Sara:> I miss explained my description (My bad).
            The callback is a managed callback into a .Net/C# method.

            So to be clear, the flow goes like this:

                 Unmanaged C++   ------->  CLI/CPP Wrapper -------->     .Net C# Client

Thanks,
JohnB
0
 
sarabandeCommented:
ok.

can you find out what the initial exception is? I mean the exception which triggers 'MyException'. you may find it in the output window of visual studio.

if you know the name of the exception you may go to debug - exceptions ... - common - language - runtime - exception and check the 'thrown' checkbox of the exception. if doing so and run again, the debugger should stop immediately and show the statement where the exception was thrown and not after it found out that there is no handler witch catches the exception.

Unable to cast object of type 'System.__ComObject' to type 'MYNameSpace.Frame'.
do you know what the __ComObject is? is it of type 'UnmanagedFrame' ? if yes, can you show the constructor of MYNameSpace::Frame(...)?

Sara
0
 
jxbmaSoftware ConsultantAuthor Commented:
::Sara::> Attached are more details regarding the exception.

FOONET.MyException: Unable to cast object of type 'System.__ComObject' to type 'FOONET.Frame'. ---> System.InvalidCastException: Unable to cast object of type 'System.__ComObject' to type 'FOONET.Frame'.
   at System.StubHelpers.InterfaceMarshaler.ConvertToManaged(IntPtr pUnk, IntPtr itfMT, IntPtr classMT, Int32 flags)
   at FOONET.ListenerImpl.onResults(ListenerImpl* , map<int\,FOO::Face\,std::less<int>\,std::allocator<std::pair<int const \,FOO::Face> > >* faces, Image* image) in c:\somefile.cpp:line 76
   --- End of inner exception stack trace ---
   at FOONET.ListenerImpl.onResults(ListenerImpl* , map<int\,FOO::Face\,std::less<int>\,std::allocator<std::pair<int const \,FOO::Face> > >* faces, Image* image) in c:\somefile.cpp:line 77
Unable to cast object of type 'System.__ComObject' to type 'FOONET.Frame'.
   at FOONET.ListenerImpl.onResults(ListenerImpl* , map<int\,FOO::Face\,std::less<int>\,std::allocator<std::pair<int const \,FOO::Face> > >* faces, Image* image) in c:somefile.cpp:line 77 

Open in new window

0
 
jxbmaSoftware ConsultantAuthor Commented:
Your comments got me pointed in the right direction.
There was an issue of when/where we were allocating the managed parameters.

Thanks,
JohnB
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now