smith
Guest
|
Posted:
Sat Sep 25, 2004 1:44 am Post subject:
is it C#, VB.net or the WMFormat function itself? A Pointer |
|
|
Hello, a while back I ported some of the most used Managed MetadataEdit
functions from the C# sample to VB.net. The functions that take care of 90%
of user
needs (GetAttributesByIndex, GetAttributeCount and SetAttribute) were easy.
But while GetAttributeCount returns the number of all of the simple custom
and most of the standard attributes, it doesn't count *All* of the standard
attributes, even if they're "simple" such as WM/Lyrics_Synchronised, so I
tried to get GetAttributeCountEX to work in VB.net, and it wouldn't budge.
The docs state that we should now be using GetAttributeCountEx instead of
GetAttributeCount and because the MS company line is that windows media is
supposed to be taking over the media world you'd think that new functions
would be *more* readily usable by *more* developers, not less by less.
In the WMFormat sample, the C# interface shows these two functions to be
"the same":
uint GetAttributeCount( [In] ushort wStreamNum,
[Out] out ushort pcAttributes );
uint GetAttributeCountEx([In] ushort wStreamNum,
[Out] out ushort pcAttributes );
And there is nothing at all special or even interesting about using the call
with C#:
ushort wStreamNum = 0;
ushort wAttributeCount = 0;
//and making the call:
HeaderInfo3.GetAttributeCountEx( wStreamNum, out wAttributeCount );
That's exactly the same as C# doing GetAttribute:
HeaderInfo3.GetAttributeCount( wStreamNum, out wAttributeCount );
The docs state that pcAttributes for GetAttributeCountEx is a pointer to a
WORD (ushort, right?) and at first glance therein lies the issue for VB:
pointers. But why?
VB.net has no problem getting back the pType and pcbLength From
GetAttributeByIndex:
C#:
uint GetAttributeByIndex([In] ushort wIndex,
[Out,In] ref ushort pwStreamNum,
[Out, MarshalAs(UnmanagedType.LPWStr)] string pwszName,
[Out,In] ref ushort pcchNameLen,
[Out] out WMT_ATTR_DATATYPE pType,
[Out, MarshalAs(UnmanagedType.LPArray)] byte[] pValue,
[Out,In] ref ushort pcbLength );
VB.Net:
Function GetAttributeByIndex(ByVal wIndex As UInt16, _
ByRef pwStreamNum As UInt16, _
<MarshalAs(UnmanagedType.LPWStr)> ByVal pwszName As String, _
ByRef pcchNameLen As UInt16, _
ByRef pType As WMT_ATTR_DATATYPE, _
<MarshalAs(UnmanagedType.LPArray)> ByVal pValue As Byte(), _
ByRef pcbLength As UInt16) As UInt32
I've even changed the pcbLength from Uint16 to Uint32 when I've found files
this pcbLengths too big for the conversion back to VB shorts and still that
call works fine.
Aren't pType and pcbLength "pointers"?
My tests of using GetAttributeCountEx have included:
1) Using it the same as GetAttributeCount by creating the pcAttribute
argument value as:
Dim wAttributeCount as Uint16
'and making the call:
HeaderInfo3.GetAttributeCountEx(Convert.ToUInt16(0), wAttributeCount)
2) explicitly forcing the value with:
Dim wAttributeCount as Uint16 = Convert.ToUint16(0)
And of course, just banging on it :)...
3) changing the function to Int and also to an IntPtr - yes, I know it's a
UInt but I took the advice of trying from Mueller's In Search of the Lost
Win32API:
Function GetAttributeCountEx(ByVal wStreamNum As UInt16, ByRef
pcAttributes As System.IntPtr) As UInt32
'and making the call with:
Dim wAttributeCount As Int16 = 0
Dim ptrAttributeCount As New System.IntPtr
ptrAttributeCount = Marshal.AllocHGlobal(ptrAttributeCount)
Marshal.WriteInt16(ptrAttributeCount, wAttributeCount)
HeaderInfo3.GetAttributeCountEx(Convert.ToUInt16(0), ptrAttributeCount)
All of these attempts return a "parameter value is incorrect" exception from
the GetAttributeCountEx function.
I didn't spend much time on this when I was doing the gig, life had to go on
so I simply put this function in a C# dll and called it from the main VB.net
project.
That gets the job done, but this little thing just keeps nagging at me,
because I'm sure that understanding the reason is going to be helpful in
lots of other projects that use other unmanaged dlls. Plus, I believe in
Windows Media even if Microsoft has decided to make it less usable, and I
find myself playing with media code quite a bit and so getting deeper into
the features with my syntax of choice would get more apps out with more
pleasure :).
Can you explain what the problem is with this "pointer" that fails when
other pointers don't? Just saying "VB.Net doesn't do pointers" isn't what
I'm hoping for because VB can do pointers to an extent that appears should
work for this call. By the way, the C# code works without having to
explicitly go UnSafe.
And if there's a more fitting newsgroup for this question, I'll take that
to.
Thanks, I appreciate your concentration.
robert smith
kirkland, wa
http://www.smithvoice.com/wmediaattrib.htm
|
|
smith
Guest
|
Posted:
Thu Sep 30, 2004 12:14 pm Post subject:
Re: is it C#, VB.net or the WMFormat function itself? A Poi |
|
|
VB.net can do these pointers just fine.
And the issue wasn't the ushort (I tested with VB2005's native unsigned
support and it failed also ... though with a NullReferenceException, not
with "parameter is not correct" or the more logical "invalid pointer"
reasons.
It was that I had not ported all of the interface functions in exactly the
right order.
I was implmenting the COM interface as if I as declaring C dll functions.
Once I ported every single function, including the ones I would never use,
up to the last one that I would use in exactly the correct order, VB.net 1.1
returned the values from the In/Out pointers without a hiccup.
So many years invested, so many new things still to learn.
Robert Smith
Kirkland, WA |
|