COM Interop issue : .Net is being too 'smart'

B

Bob S

I am having trouble with the following scenario....

Assembly A
Returns a managed implementation of COM IStream interface to the
unmanaged world
=============

/////////////////
[ComImport]
[GUID("..")]
interface IStreamAssemblyA
{
...
}

class MyStreamImpl : IStreamAssemblyA
{
..........
}

IntPtr GetStreamImpl()
{
MyStreamImpl obj = new MyStreamImpl();
IntPtr ret =
Marshal.GetComInterfaceForObject(obj,typeof(IStreamAssemblyA));
return ret;
}
///////////////////


Assembly B
Gets and uses a COM IStream interface from the unmanaged world. In
case the implementation is an unmanaged one, everything works OK. In
case the implementation is actually from assembly A above (or any
other managed implementation), the cast fails as shown below.....
==========

/////////////////
[ComImport]
[GUID("..")]
interface IStreamAssemblyB
{
...
}

IntPtr GetStreamFromUnmanagedWorld()
{
...
}

void UseStream()
{
IntPtr streamUnk = GetStreamFromUnmanagedWorld();

object obj = Marshal.GetObjectForIUnknown(streamUnk); // obj is
actually class MyStreamImpl from assembly A above

IStreamAssemblyB stream = obj as IStreamAssemblyB; // this fails
becuase of different ".Net type" of obj and stream
}
/////////////////


The above problem exists becuase .Net does not recognize that even though
IStreamAssemblyA and IStreamAssemblyB are different ".Net types" they are
actually COM interfaces imported into .Net and so the cast above should be
allowed (and QueryInterface should be used internally).

How can I solve this issue? Its not possible to have a common IStream
declartion becuase AssemblyA and AssemblyB are not related in any way except
to the extent that assembly B happens to use the managed IStream
implementation from assembly A.

Any help would be appreciated!

Bob
 
T

TDC

Create AssembyC in which you place IStreamAssemblyCommon and then
reference that from both A and B.
 
B

Bob S

As I said, its not possible to have a common IStream becuase assembly A (the
managed implementation) is not under my control. I could be consuming a
managed implementation from any arbitrary 3rd party assembly.

Bob



TDC said:
Create AssembyC in which you place IStreamAssemblyCommon and then
reference that from both A and B.


Bob said:
I am having trouble with the following scenario....

Assembly A
Returns a managed implementation of COM IStream interface to the
unmanaged world
=============

/////////////////
[ComImport]
[GUID("..")]
interface IStreamAssemblyA
{
..
}

class MyStreamImpl : IStreamAssemblyA
{
.........
}

IntPtr GetStreamImpl()
{
MyStreamImpl obj = new MyStreamImpl();
IntPtr ret =
Marshal.GetComInterfaceForObject(obj,typeof(IStreamAssemblyA));
return ret;
}
///////////////////


Assembly B
Gets and uses a COM IStream interface from the unmanaged world. In
case the implementation is an unmanaged one, everything works OK. In
case the implementation is actually from assembly A above (or any
other managed implementation), the cast fails as shown below.....
==========

/////////////////
[ComImport]
[GUID("..")]
interface IStreamAssemblyB
{
..
}

IntPtr GetStreamFromUnmanagedWorld()
{
..
}

void UseStream()
{
IntPtr streamUnk = GetStreamFromUnmanagedWorld();

object obj = Marshal.GetObjectForIUnknown(streamUnk); // obj is
actually class MyStreamImpl from assembly A above

IStreamAssemblyB stream = obj as IStreamAssemblyB; // this fails
becuase of different ".Net type" of obj and stream
}
/////////////////


The above problem exists becuase .Net does not recognize that even though
IStreamAssemblyA and IStreamAssemblyB are different ".Net types" they are
actually COM interfaces imported into .Net and so the cast above should
be
allowed (and QueryInterface should be used internally).

How can I solve this issue? Its not possible to have a common IStream
declartion becuase AssemblyA and AssemblyB are not related in any way
except
to the extent that assembly B happens to use the managed IStream
implementation from assembly A.

Any help would be appreciated!

Bob
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top