Using IImagingFactory etc from CF 2.0, crashing the debugging sess

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Has anyone tried wrapping all of these interfaces up? I've been playing
around with doing this for IImagingFactory and have been gradually working
through the tree of calls. Some of them work they way I'd expect. Others
are creating some unusual problems. For example, I've created the following:
namespace IImageTesting
{
[ComImportAttribute()]
[GuidAttribute("0000000c-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
public interface IStream
{
int Read(IntPtr buffer, int numBytes, out int numRead);

int Write(IntPtr buffer, int numBytes, out int numWritter);

int Seek(long position, int origin, out long newPosition);

int SetSize(long newSize);

int CopyTo(IStream pstm, long numBytes, out long numRead, out long
numWritten);

int Commit(int commitFlags);

int Revert();

int LockRegion(long offset, long numBytes, int lockType);

int UnlockRegion(long offset, long numBytes, int lockType);

int Stat(ref StatStg statBuf, int statFlag);

int Clone(out IStream stm);
}
}

And then use it here:
[ClassInterface(ClassInterfaceType.None)]
public class StreamInIStream : IStream
{
private Stream _stm;
public StreamInIStream(Stream stm)
{
_stm = stm;
}
#region IStream Members
// boring details removed for brevity
#endregion
}

in this context:
FileStream stm = new FileStream("\\Program
Files\\IImageTesting\\4bit.bmp",
FileMode.Open);
StreamInIStream istm = new StreamInIStream(stm);
factory.CreateImageFromStream(istm, out blah);
At this point, CreateImageFromStream crashes the session with the
wonderfully descriptive error number 800704ca, which gives me this if I
search for it through the SDK header files:
Find all "800704ca", Match case, Subfolders, Find Results 1, "WinCE 5.0
includes", "*.h"
Matching lines: 0 Matching files: 0 Total files searched: 551

Ideas?

I'd like to be able to author my own codecs and image sinks in .NET, but
this isn't giving me warm fuzzies about that process.
 
You seem to be missing marshalling attributes on your interface description.
Try this one (I have not tried it myself)

[ComImport, Guid("0000000c-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IStream
{
void Read([Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]
byte[] pv, int cb, IntPtr pcbRead);
void Write([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] byte[]
pv, int cb, IntPtr pcbWritten);
void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition);
void SetSize(long libNewSize);
void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten);
void Commit(int grfCommitFlags);
void Revert();
void LockRegion(long libOffset, long cb, int dwLockType);
void UnlockRegion(long libOffset, long cb, int dwLockType);
void Stat(out STATSTG pstatstg, int grfStatFlag);
void Clone(out IStream ppstm);
}
plinth said:
Has anyone tried wrapping all of these interfaces up? I've been playing
around with doing this for IImagingFactory and have been gradually working
through the tree of calls. Some of them work they way I'd expect. Others
are creating some unusual problems. For example, I've created the
following:
namespace IImageTesting
{
[ComImportAttribute()]
[GuidAttribute("0000000c-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
public interface IStream
{
int Read(IntPtr buffer, int numBytes, out int numRead);

int Write(IntPtr buffer, int numBytes, out int numWritter);

int Seek(long position, int origin, out long newPosition);

int SetSize(long newSize);

int CopyTo(IStream pstm, long numBytes, out long numRead, out long
numWritten);

int Commit(int commitFlags);

int Revert();

int LockRegion(long offset, long numBytes, int lockType);

int UnlockRegion(long offset, long numBytes, int lockType);

int Stat(ref StatStg statBuf, int statFlag);

int Clone(out IStream stm);
}
}

And then use it here:
[ClassInterface(ClassInterfaceType.None)]
public class StreamInIStream : IStream
{
private Stream _stm;
public StreamInIStream(Stream stm)
{
_stm = stm;
}
#region IStream Members
// boring details removed for brevity
#endregion
}

in this context:
FileStream stm = new FileStream("\\Program
Files\\IImageTesting\\4bit.bmp",
FileMode.Open);
StreamInIStream istm = new StreamInIStream(stm);
factory.CreateImageFromStream(istm, out blah);
At this point, CreateImageFromStream crashes the session with the
wonderfully descriptive error number 800704ca, which gives me this if I
search for it through the SDK header files:
Find all "800704ca", Match case, Subfolders, Find Results 1, "WinCE 5.0
includes", "*.h"
Matching lines: 0 Matching files: 0 Total files searched: 551

Ideas?

I'd like to be able to author my own codecs and image sinks in .NET, but
this isn't giving me warm fuzzies about that process.
 
Thanks - here's what I found:
1. The crash was happening in Seek because the out long newPosition was
being sent in as null (which means "I don't care about the new position") - I
changed it to IntPtr and made the appropriate code changes.
The same crash happens later now. I've got breakpoints set at the entry in
every method in the interface implementation and none are getting hit. This
leads me to believe that the problem might be in the definition of the
interface itself.
IStream in the header files is defined as inheriting from ISequentialStream.
I made the assumption that the vtables would just be sequential so I just
injected the member declarations into the IStream. I'm assuming that this is
a mistake.

Now, here's a vent for my frustration: is there anywhere where the process
of wrapping of COM interfaces is documented properly? What I've stumbled
upon is basically "add the COM object to the reference in your project and it
will just work", which unfortunately is not an option in CF.

Furthermore, I'd like to see the IImagingFactory, IImage, and other
interfaces actually documented as to their intended use. The existing
documentation is very much in the category of "what", but this section of
code needs both a "why" and "how" level of documentation. I went through the
sample code in the CE 5.0 SDK and found one example which only does the bare
minimum, and thanks, I already figured that much out.

It'd be nice to see something clear and coherent along the lines of, "here's
how you write your own codec". "here's how you can expect your codec to be
called by an IImageSink" "here's how you write your own sink" "Here's the
overall architecture and relationship of the objects in this space and the
intent"
 
Back
Top