C# .NET - How to implement IPersistStream Interface in c#

Asked By svt gdwl on 05-Jun-09 08:33 AM
end of post

try this - Sakshi a replied to svt gdwl on 05-Jun-09 09:02 AM

social.msdn.microsoft.com/Forums/en-US/windowsdesktopsearchdevelopment/thread/64eb9907


You can use the ComImport Attribute to implement the IPersistStream Interface

[)ia6l0 iii replied to svt gdwl on 05-Jun-09 09:26 AM
Like, 

[ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),Guid("00000109-0000-0000-C000-000000000046")]
public interface IPersistStream : IPersist
{
new void GetClassID(out Guid pClassID);
int IsDirty();
void GetSizeMax(out long pcbSize);
void Save([In] UCOMIStream pStm, [In, MarshalAs(UnmanagedType.Bool)] bool fClearDirty); void Load([In] UCOMIStream pStm);
};

and also since IPersistStream inherits from IPersist you need to do this too.

[ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),Guid("0000010c-0000-0000-C000-000000000046")]
public interface IPersist
{
void GetClassID();
};

RE - Ravenet Rasaiyah replied to svt gdwl on 05-Jun-09 09:42 AM

Hi

Here implementation code


using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;

namespace ESRI.APL.Utility
{
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("0000010c-0000-0000-C000-000000000046")]
public interface IPersist {
void GetClassID(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] IStream pStm);
void Save([In] IStream pStm, [In, MarshalAs(UnmanagedType.Bool)] bool fClearDirty);
void GetSizeMax(out long pcbSize);
};

[ComVisible(false)]
internal sealed class PeristStream {
unsafe internal static object Load(IStream stream) {
// Exit if Stream is NULL
if (stream == null) { return null; }

//
object data = null;

// Get Pointer to Int32
int cb;
int* pcb = &cb;

// Get Size of DataTable Byte Array
byte[] arrLen = new Byte[4];
stream.Read(arrLen, arrLen.Length, new IntPtr(pcb));
cb = BitConverter.ToInt32(arrLen, 0);

// Read DataTable Byte Array
byte[] bytes = new byte[cb];
stream.Read(bytes, cb, new IntPtr(pcb));

AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new ResolveEventHandler(PeristStream.ResolveEventHandler);

// Deserialize byte array
MemoryStream memoryStream = new MemoryStream(bytes);
BinaryFormatter binaryFormatter = new BinaryFormatter();
object objectDeserialize = binaryFormatter.Deserialize(memoryStream);
if (objectDeserialize != null) {
data = objectDeserialize;
}
memoryStream.Close();

currentDomain.AssemblyResolve -= new ResolveEventHandler(PeristStream.ResolveEventHandler);

//
return data;
}
unsafe internal static void Save(IStream stream, object data) {
// Exit if Stream or DataTable is NULL
if (stream == null) { return; }
if (data == null) { return; }

// Convert DataTable to Byte Array
MemoryStream memoryStream = new MemoryStream();
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(memoryStream, data);
byte[] bytes = memoryStream.ToArray();
memoryStream.Close();

// Get Memory Pointer to Int32
int cb;
int* pcb = &cb;

// Save Data
byte[] arrLen = BitConverter.GetBytes(bytes.Length); // Get Byte Length
stream.Write(arrLen, arrLen.Length, new IntPtr(pcb)); // Write Byte Length
stream.Write(bytes, bytes.Length, new IntPtr(pcb)); // Write Btye Array
}
private static Assembly ResolveEventHandler(object sender, ResolveEventArgs args) {
Assembly assembly = null;
for (int i = 0; i <= AppDomain.CurrentDomain.GetAssemblies().Length - 1; i++) {
if (args.Name.Split(",".ToCharArray())[0].ToUpper() ==
AppDomain.CurrentDomain.GetAssemblies()[i].FullName.Split(",".ToCharArray())[0].ToUpper()) {
assembly = AppDomain.CurrentDomain.GetAssemblies()[i];
break;
}
}
return assembly;
}
}

#region Test Class for PersistStream [COMMENTED OUT]
[ComVisible(true)]
[Guid(TestPersistStream.GUID)]
public sealed class TestPersistStream : IPersistStream {
public const string GUID = "C97C7707-3A8B-4933-953E-8AF605851FCC";

private string m_name = string.Empty;

public TestPersistStream() {
this.m_name = "Hello World";
}
~TestPersistStream() { }
public void GetClassID(out Guid pClassID) {
pClassID = new Guid(TestPersistStream.GUID);
}
public int IsDirty() {
return 0;
}
public void Load(UCOMIStream pStm) {
this.m_name = (string)PeristStream.Load(pStm);
}
public void Save(UCOMIStream pStm, bool fClearDirty) {
PeristStream.Save(pStm, this.m_name);
}
public void GetSizeMax(out long pcbSize) {
pcbSize = 0;
}
}
#endregion
}

Check here more details

http://mrrichie.spaces.live.com/blog/cns%21DD16C3F34F4D913E%21331.entry

thank you