Reputation: 2116
This method is to get the MIME type from a Byte array in C#. I got most of the code already converted to VB.Net, however I am struggling with parts of it
C# Code
[DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]
static extern int FindMimeFromData(IntPtr pBC,
[MarshalAs(UnmanagedType.LPWStr)] string pwzUrl,
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1, SizeParamIndex = 3)]
byte[] pBuffer,
int cbSize,
[MarshalAs(UnmanagedType.LPWStr)] string pwzMimeProposed,
int dwMimeFlags,
out IntPtr ppwzMimeOut,
int dwReserved);
public static string GetMimeFromBytes(byte[] data) {
int MimeSampleSize = 256;
string DefaultMimeType = "application/octet-stream";
if (data == null) {
throw new ArgumentNullException("data", "Hey, data is null.");
}
IntPtr mimeTypePointer = IntPtr.Zero;
try {
FindMimeFromData(IntPtr.Zero, null, data, MimeSampleSize, null, 0, out mimeTypePointer, 0);
var mime = Marshal.PtrToStringUni(mimeTypePointer);
return mime ?? DefaultMimeType;
} catch (AccessViolationException e) {
//Debug.WriteLine(e.ToString());
return DefaultMimeType;
} finally {
if (mimeTypePointer != IntPtr.Zero) {
Marshal.FreeCoTaskMem(mimeTypePointer);
}
}
}
Vb.Net (with errors)
<DllImport("urlmon.dll", CharSet:=CharSet.Unicode, ExactSpelling:=True, SetLastError:=False)> _
Function FindMimeFromData(pBC As IntPtr, _
<MarshalAs(UnmanagedType.LPWStr)> ByVal pwzUrl As String, _
<MarshalAs(UnmanagedType.LPArray, ArraySubType:=UnmanagedType.I1, SizeParamIndex:=3)> ByVal pBuffer() As Byte, _
cbSize As Integer, _
<MarshalAs(UnmanagedType.LPWStr)> ByVal pwzMimeProposed As String, _
dwMimeFlags As Integer, _
<OutAttribute> ppwzMimeOut As IntPtr, _
dwReserved As Integer) As Integer
End Function
Public Function GetMimeFromBytes(data() As Byte) As String
Dim MimeSampleSize As Integer = 256
Dim DefaultMimeType As String = "application/octet-stream"
If data == null Then
Throw New ArgumentNullException("data", "Hey, data is null.")
End If
Dim mimeTypePointer As IntPtr = IntPtr.Zero
Try
FindMimeFromData(IntPtr.Zero, null, data, MimeSampleSize, null, 0, out mimeTypePointer, 0)
Dim mime = Marshal.PtrToStringUni(mimeTypePointer)
return mime ?? DefaultMimeType
Catch e As AccessViolationException
Return DefaultMimeType
Finally
If Not mimeTypePointer = IntPtr.Zero Then
Marshal.FreeCoTaskMem(mimeTypePointer)
End If
End Try
End Function
The following are the errors i have
Function FindMimeFromData(pBC As IntPtr
DllImport cannot be applied to instance method
If data == null Then
null is not declared. Null constant is no longer supported. use System.BDNull
instead. When I change it to System.BDNull
is telling me that it can't be used as an expression
out mimeTypePointer, 0)
out is not declared
<OutAttribute> ppwzMimeOut As IntPtr, _
here should I be using <OutAttribute>
or ByRef
Thanks
Upvotes: 0
Views: 1671
Reputation: 933
I don't know what errors you might be having are... but I work in both languages simultaneously and constantly, and from what I can see, the exact translation for the C# code, above, is:
<DllImport("urlmon.dll", CharSet:=CharSet.Unicode, ExactSpelling:=True, SetLastError:=False)> _
Public Shared Function FindMimeFromData(pBC As IntPtr, _
<MarshalAs(UnmanagedType.LPWStr)>
pwzUrl As String, _
<MarshalAs(UnmanagedType.LPArray, ArraySubType:=UnmanagedType.U1, SizeParamIndex:=3)>
pBuffer() As Byte, _
cbSize As Integer, _
<MarshalAs(UnmanagedType.LPWStr)>
pwzMimeProposed As String, _
dwMimeFlags As Integer, _
ByRef ppwzMimeOut As IntPtr, _
dwReserved As Integer) As Integer
End Function
Public Shared Function GetMimeFromBytes(data As Byte()) As String
Dim MimeSampleSize As Integer = 256
Dim DefaultMimeType As String = "application/octet-stream"
If (data Is Nothing) Then
Throw New ArgumentNullException("data", "Hey, data is null.")
End If
Dim mimeTypePointer As IntPtr = IntPtr.Zero
Try
FindMimeFromData(IntPtr.Zero, Nothing, data, MimeSampleSize, Nothing, 0, mimeTypePointer, 0)
Dim mime As String = Marshal.PtrToStringUni(mimeTypePointer)
Return If((mime IsNot Nothing) AndAlso (mime <> ""), mime, DefaultMimeType)
Catch ex As AccessViolationException
'Debug.WriteLine(e.ToString())
Return DefaultMimeType
Finally
If (mimeTypePointer <> IntPtr.Zero) Then
Marshal.FreeCoTaskMem(mimeTypePointer)
End If
End Try
End Function
Now. If you run into problems with the LPArray being Null, that might be something to consider, you might want to make that an IntPtr (or ByRef IntPtr, depending on what the case is, here), and then convert the IntPtr to array using a Marshal.Copy or some such...
... however, one thing I can tell you, is that if the function succeeds, Marshal.FreeCoTaskMem might never be called... I'm not sure about the Finally block behavior on Return, but I would never have written it that way, in VB. Because, in VB, you would want to write the code this way:
<DllImport("urlmon.dll", CharSet:=CharSet.Unicode, ExactSpelling:=True, SetLastError:=False)> _
Public Shared Function FindMimeFromData(pBC As IntPtr, _
<MarshalAs(UnmanagedType.LPWStr)>
pwzUrl As String, _
<MarshalAs(UnmanagedType.LPArray, ArraySubType:=UnmanagedType.U1, SizeParamIndex:=3)>
pBuffer() As Byte, _
cbSize As Integer, _
<MarshalAs(UnmanagedType.LPWStr)>
pwzMimeProposed As String, _
dwMimeFlags As Integer, _
ByRef ppwzMimeOut As IntPtr, _
dwReserved As Integer) As Integer
End Function
Public Shared Function GetMimeFromBytes(data As Byte()) As String
Dim MimeSampleSize As Integer = 256
Dim DefaultMimeType As String = "application/octet-stream"
If (data Is Nothing) Then
Throw New ArgumentNullException("data", "Hey, data is null.")
End If
Dim mimeTypePointer As IntPtr = IntPtr.Zero
Try
FindMimeFromData(IntPtr.Zero, Nothing, data, MimeSampleSize, Nothing, 0, mimeTypePointer, 0)
Dim mime As String = Marshal.PtrToStringUni(mimeTypePointer)
GetMimeFromBytes = CType(If((mime IsNot Nothing) AndAlso (mime <> ""), mime, DefaultMimeType), String)
Catch ex As AccessViolationException
'Debug.WriteLine(e.ToString())
GetMimeFromBytes = DefaultMimeType
Finally
If (mimeTypePointer <> IntPtr.Zero) Then
Marshal.FreeCoTaskMem(mimeTypePointer)
End If
End Try
End Function
And this code validates with Option Strict On, so ... Option Infer On is probably not necessary.
Upvotes: 0
Reputation: 6542
You need to set 'Option Infer On' ('mime' uses inferred typing) and the following should work fine:
<DllImport("urlmon.dll", CharSet := CharSet.Unicode, ExactSpelling := True, SetLastError := False)> _
Shared Function FindMimeFromData(ByVal pBC As IntPtr, <MarshalAs(UnmanagedType.LPWStr)> ByVal pwzUrl As String, <MarshalAs(UnmanagedType.LPArray, ArraySubType := UnmanagedType.I1, SizeParamIndex := 3)> ByVal pBuffer() As Byte, ByVal cbSize As Integer, <MarshalAs(UnmanagedType.LPWStr)> ByVal pwzMimeProposed As String, ByVal dwMimeFlags As Integer, ByRef ppwzMimeOut As IntPtr, ByVal dwReserved As Integer) As Integer
End Function
Public Shared Function GetMimeFromBytes(ByVal data() As Byte) As String
Dim MimeSampleSize As Integer = 256
Dim DefaultMimeType As String = "application/octet-stream"
If data Is Nothing Then
Throw New ArgumentNullException("data", "Hey, data is null.")
End If
Dim mimeTypePointer As IntPtr = IntPtr.Zero
Try
FindMimeFromData(IntPtr.Zero, Nothing, data, MimeSampleSize, Nothing, 0, mimeTypePointer, 0)
Dim mime = Marshal.PtrToStringUni(mimeTypePointer)
Return If(mime, DefaultMimeType)
Catch e As AccessViolationException
'Debug.WriteLine(e.ToString());
Return DefaultMimeType
Finally
If mimeTypePointer <> IntPtr.Zero Then
Marshal.FreeCoTaskMem(mimeTypePointer)
End If
End Try
End Function
Upvotes: 1
Reputation: 5994
Function FindMimeFromData(pBC As IntPtr
Make it Shared
. Shared = static.
If data == null Then null is not declared. Null constant is no longer supported. use System.BDNull instead. When I change it to System.BDNull is telling me that it can't be used as an expression
== operator is only available in c#. Use the = operator instead. The =
operator in vb.net equals the ==
operator in c#.
out mimeTypePointer, 0) out is not declared ppwzMimeOut As IntPtr, _ here should I be using or ByRef
Declare it as ByRef ppwzMimeOut As IntPtr
and remove the out
keyword.
Upvotes: 1