I'm trying to pass an object as a parameter to a queued component. I know
that the class needs to implement the IPersistStream interface, but I'm
still having problems. First, I'm defining the IPersistStream interface in
my code as follows:
//Definition for interface IPersistStream.
[ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("0000010c-0000-0000-C000-000000000046")]
public interface IPersist
{
void GetClassID( /* [out] */ out Guid pClassID);
};
[ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("00000109-0000-0000-C000-000000000046")]
public interface IPersistStream : IPersist
{
new void GetClassID(out Guid pClassID);
[PreserveSig]
int IsDirty();
void Load([In] UCOMIStream pStm);
void Save([In] UCOMIStream pStm, [In, MarshalAs(UnmanagedType.Bool)] bool
fClearDirty);
void GetSizeMax(out long pcbSize);
};
Next, I define the class that I'm trying to pass as a parameter, and I
implement the IPersistStream methods
void IPersist.GetClassID(out Guid pClassID)
{
pClassID = Marshal.GenerateGuidForType( this.GetType());
}
void IPersistStream.GetClassID(out Guid pClassID)
{
pClassID = Marshal.GenerateGuidForType( this.GetType());
}
int IPersistStream.IsDirty()
{
log.WriteEntry(@"IMyPersistStreamImpl::IsDirty");
return m_bRequiresSave ? 0 : -1;
}
//called when instantiating the object from the stream.
unsafe void IPersistStream.Load([In] UCOMIStream pStm)
{
log.WriteEntry(@"IMyPersistStreamImpl::Load");
[... code omitted for brevity...]
}
//called when saving the object in the stream
unsafe void IPersistStream.Save([In] UCOMIStream pStm, [In,
MarshalAs(UnmanagedType.Bool)] bool fClearDirty)
{
log.WriteEntry(@"IMyPersistStreamImpl::Save");
[... code omitted for brevity...]
}
void IPersistStream.GetSizeMax(out long pcbSize)
{
log.WriteEntry(@"IMyPersistStreamImpl::GetSizeMax");
[... code omitted for brevity...]
}
Finally, I call my queued component, and I go look at the Event log. I can
tell that none of the members of the IPersistStream interface have been
called, but I do find the following errors in the event log.
Object reference passed as a method parameter to a Queued Component does not
implement IPersistStream.IPersistStream::Save
and
Object reference passed as a method parameter to a Queued Component does not
implement IPersistStream.CMarshalInterceptor::GetSizeMax and Save
This, despite the fact that I have done my darndest to implement those very
methods! I've been beating my head against the wall for a while now on
this, and I'm about to rewrite my code to pass all the arguments in as
individual primitive types, although it isn't as elegant. However, I
thought I'd make one last try and see if anyone out there had any
suggestions.
By the way, I have tried both defining the methods that implement the
IPersistStream interface with the usual implicit interface syntax
e.g. public void GetSizeMax(out long pcbSize)
and with the explicit interface syntax
e.g. void IPersistStream.GetSizeMax(out long pcbSize)
It doesn't appear to make a difference one way or the other.
Oh yes, and I'm using Visual Studio.NET 2003, and Windows XP Professional,
although the components will eventually be deployed on Windows Server 2003.
Thanks for any suggestions...
Laura
Stingray - 16 Oct 2003 20:22 GMT
Laura,
I don't know if this will help your situation, but I had a similar problem a
while back where I couldn't pass an object in a QC parameter. I don't
remember now exactly what the error was. But what I did to get around it
was serialize the object to a byte array, pass the byte array, then
deserialize it back. It was a kludge, but it worked and it beat passing 18
individual primitives. Like you, I posted to these newsgroups but did not
get a useful reply. I figured I must be in uncharted waters so I went with
the kludge temporarily. This temporarily kludge has been in production for
almost a year now. :)
HTH,
John
> I'm trying to pass an object as a parameter to a queued component. I know
> that the class needs to implement the IPersistStream interface, but I'm
[quoted text clipped - 91 lines]
>
> Laura
Brad King - 16 Oct 2003 23:05 GMT
I think I read somewhere that the QC interop layer doesn't support the com
notion of persistence (IPersistStream and friends). I did a similar thing as
Stingray, using byte[]. Its not as ugly as you might think with the built in
formatters.
> Laura,
> I don't know if this will help your situation, but I had a similar problem a
[quoted text clipped - 110 lines]
> >
> > Laura