M
Mike
Folks,
I think this ok and probably should not worry about it and look at it
as some future point, but I am wondering if the following should be
done another way.
Background:
In our SDK, it makes extensive use of the 8 byte FILETIME Win32
structure which is defined (in C/C++)
typedef struct _FILETIME {
DWORD dwLowDateTime;
DWORD dwHighDateTime;
} FILETIME, *PFILETIME;
A DWORD (Double Word) is an unsigned int32.
In VB.NET, it would be:
Public Structure FILETIME
Public dwLowDateTime As UInteger
Public dwHighDateTime As UInteger
End Structure
Side Note: I understand there is already a FILETIME in
System.Runtime.InteropServices.ComTypes.FILETIME
But I don't wish to bind to any more assemblies if I don't
have to or require developers have to import it for each source
code plus, when you use COMTYPE.FILETIME, you get tons of silly
IDE underscores and compiler warnings about compatibility. So
I am sticking with my own FILETIME. If someone feels there
a good reason to use COMTYPE.FILETIME, please comment.
Now, this is only one step in creating the SDK. The usefulness is how
its employed and used easily by developers close to the way they are
using it now. So in the spirits and elegance of VB.NET OOPs and type
conversion automation, I added a bunch of operators:
Public Structure FILETIME
Public dwLowDateTime As UInteger
Public dwHighDateTime As UInteger
Public Sub new(hi as Uinteger, lo as Uinteger)
dwHighDateTime = hi
dwLowDateTime = lo
End Sub
' convert Operator for converting self to long
Public Shared Widening Operator CType(ft As FILETIME) As Long
Return MakeLong64(ft)
End Operator
' convert Operator for assigning a long
Public Shared Widening Operator CType(l As long) As FILETIME
Dim bytes() As Byte = BitConverter.GetBytes(l)
dim lo as UInteger = BitConverter.ToUInt32(bytes, 0)
dim hi as UInteger = BitConverter.ToUint32(bytes, 4)
Return new FILETIME(hi,lo)
End Operator
' convert operator for assigning a Datetime
Public Shared Widening Operator CType(dt As DateTime) As FILETIME
Dim bytes() As Byte = BitConverter.GetBytes(dt.ToBinary())
dim lo as UInteger = BitConverter.ToUInt32(bytes, 0)
dim hi as UInteger = BitConverter.ToUint32(bytes, 4)
Return new FILETIME(hi,lo)
End Operator
' convert operator for assiging a FILETIME and returning Datetime
Public Shared Widening Operator CType(ft As FILETIME) As DateTime
Return DateTime.FromBinary(MakeLong64(ft))
End Operator
' operator: return diff in seconds
Public Shared Operator -(lt As FILETIME, rt as FILETIME) As long
Return (MakeLong64(lt)-MakeLong64(rt))/10000000
End Operator
' operator: compare less than
Public Shared Operator < (lt As FILETIME, rt as FILETIME) _
As boolean
Return MakeLong64(lt) < MakeLong64(rt)
End Operator
' operator: compare greater than
Public Shared Operator > (lt As FILETIME, rt as FILETIME) _
As boolean
Return MakeLong64(lt) > MakeLong64(rt)
End Operator
' operator: compare greater/equal than
Public Shared Operator >= (lt As FILETIME, rt as FILETIME) _
As boolean
Return MakeLong64(lt) >= MakeLong64(rt)
End Operator
' operator: compare less/equal than
Public Shared Operator <= (lt As FILETIME, rt as FILETIME) _
As boolean
Return MakeLong64(lt) <= MakeLong64(rt)
End Operator
' operator: compare equal
Public Shared Operator = (lt As FILETIME, rt as FILETIME) _
As boolean
Return MakeLong64(lt) = MakeLong64(rt)
End Operator
' operator: compare not equal
Public Shared Operator <> (lt As FILETIME, rt as FILETIME) _
As boolean
Return MakeLong64(lt) <> MakeLong64(rt)
End Operator
Public Overrides Function ToString() as string
return DateTime.FromBinary( _
MakeLong64(dwHighDateTime, dwLowDateTime))
end function
End Structure
These two functions are part of my DATELIB.VB class
Public Function MakeLong64(hi As object, lo As object) As Long
Return CLng(CLng(hi) << 32) + CLng(lo)
End Function
Public Function MakeLong64(ft As FILETIME) As Long
Return MakeLong64(ft.dwHighDateTime, ft.dwLowDateTime)
End Function
All those provides various ways to convert between FILETIME
and DATETIME:
sub DoDateTest1()
dim [now] as datetime = DateTime.Now()
dim ft1 as FILETIME = [now].ToBinary()
dim ft2 as FILETIME = [now]
dim ft3 as New FILETIME(ft2.dwHighDateTime, ft2.dwLowDateTime)
dim dt4 as DateTime = ft3
dim dt5 as DateTime = dt4.AddSeconds(30)
dim ft6 as FILETIME = dt5
dim diff7 as long = ft6 - ft2
dim ft8 as FileTime = dt4.AddYears(1)
Console.WriteLine("now: {0,25} ", [now])
Console.WriteLine("ft1: {0,25} ", ft1)
Console.WriteLine("ft2: {0,25} ", ft2)
Console.WriteLine("ft3: {0,25} ", ft3)
Console.WriteLine("dt4: {0,25} ", dt4)
Console.WriteLine("dt4: {0,25} ", dt5)
Console.WriteLine("ft6: {0,25} ", ft6)
Console.WriteLine("diff7: {0,25} ", diff7)
Console.WriteLine("ft6 > ft2: {0}", ft6 > ft2) 'expect true
Console.WriteLine("ft1 = ft2: {0}", ft1 = ft2) 'expect true
Console.WriteLine("ft1 <>ft2: {0}", ft1 <> ft2) 'expect false
Console.WriteLine("ft8: {0,25} ", ft8)
end sub
My questions to the VB.NET experts:
1) Is using this structure FILETIME with all these operator going to
be a performance hit?
2) Related to #1, should I break this up? A Structure and a Class?
There were two things that made think about it:
- Desire to separate SDK library with wrapper classes;
a base SDK library with structures and API function imports,
and a wrapper library for usability.
- The SDK has many structures that use the FILETIME. Thinking
there might be RTTI and serialization overhead during the
marshalling. Even if negligible, is there a preferred
alternative to reduce redundancy?
Any tips, suggestions, comments, "Got chas?"
thanks
--
I think this ok and probably should not worry about it and look at it
as some future point, but I am wondering if the following should be
done another way.
Background:
In our SDK, it makes extensive use of the 8 byte FILETIME Win32
structure which is defined (in C/C++)
typedef struct _FILETIME {
DWORD dwLowDateTime;
DWORD dwHighDateTime;
} FILETIME, *PFILETIME;
A DWORD (Double Word) is an unsigned int32.
In VB.NET, it would be:
Public Structure FILETIME
Public dwLowDateTime As UInteger
Public dwHighDateTime As UInteger
End Structure
Side Note: I understand there is already a FILETIME in
System.Runtime.InteropServices.ComTypes.FILETIME
But I don't wish to bind to any more assemblies if I don't
have to or require developers have to import it for each source
code plus, when you use COMTYPE.FILETIME, you get tons of silly
IDE underscores and compiler warnings about compatibility. So
I am sticking with my own FILETIME. If someone feels there
a good reason to use COMTYPE.FILETIME, please comment.
Now, this is only one step in creating the SDK. The usefulness is how
its employed and used easily by developers close to the way they are
using it now. So in the spirits and elegance of VB.NET OOPs and type
conversion automation, I added a bunch of operators:
Public Structure FILETIME
Public dwLowDateTime As UInteger
Public dwHighDateTime As UInteger
Public Sub new(hi as Uinteger, lo as Uinteger)
dwHighDateTime = hi
dwLowDateTime = lo
End Sub
' convert Operator for converting self to long
Public Shared Widening Operator CType(ft As FILETIME) As Long
Return MakeLong64(ft)
End Operator
' convert Operator for assigning a long
Public Shared Widening Operator CType(l As long) As FILETIME
Dim bytes() As Byte = BitConverter.GetBytes(l)
dim lo as UInteger = BitConverter.ToUInt32(bytes, 0)
dim hi as UInteger = BitConverter.ToUint32(bytes, 4)
Return new FILETIME(hi,lo)
End Operator
' convert operator for assigning a Datetime
Public Shared Widening Operator CType(dt As DateTime) As FILETIME
Dim bytes() As Byte = BitConverter.GetBytes(dt.ToBinary())
dim lo as UInteger = BitConverter.ToUInt32(bytes, 0)
dim hi as UInteger = BitConverter.ToUint32(bytes, 4)
Return new FILETIME(hi,lo)
End Operator
' convert operator for assiging a FILETIME and returning Datetime
Public Shared Widening Operator CType(ft As FILETIME) As DateTime
Return DateTime.FromBinary(MakeLong64(ft))
End Operator
' operator: return diff in seconds
Public Shared Operator -(lt As FILETIME, rt as FILETIME) As long
Return (MakeLong64(lt)-MakeLong64(rt))/10000000
End Operator
' operator: compare less than
Public Shared Operator < (lt As FILETIME, rt as FILETIME) _
As boolean
Return MakeLong64(lt) < MakeLong64(rt)
End Operator
' operator: compare greater than
Public Shared Operator > (lt As FILETIME, rt as FILETIME) _
As boolean
Return MakeLong64(lt) > MakeLong64(rt)
End Operator
' operator: compare greater/equal than
Public Shared Operator >= (lt As FILETIME, rt as FILETIME) _
As boolean
Return MakeLong64(lt) >= MakeLong64(rt)
End Operator
' operator: compare less/equal than
Public Shared Operator <= (lt As FILETIME, rt as FILETIME) _
As boolean
Return MakeLong64(lt) <= MakeLong64(rt)
End Operator
' operator: compare equal
Public Shared Operator = (lt As FILETIME, rt as FILETIME) _
As boolean
Return MakeLong64(lt) = MakeLong64(rt)
End Operator
' operator: compare not equal
Public Shared Operator <> (lt As FILETIME, rt as FILETIME) _
As boolean
Return MakeLong64(lt) <> MakeLong64(rt)
End Operator
Public Overrides Function ToString() as string
return DateTime.FromBinary( _
MakeLong64(dwHighDateTime, dwLowDateTime))
end function
End Structure
These two functions are part of my DATELIB.VB class
Public Function MakeLong64(hi As object, lo As object) As Long
Return CLng(CLng(hi) << 32) + CLng(lo)
End Function
Public Function MakeLong64(ft As FILETIME) As Long
Return MakeLong64(ft.dwHighDateTime, ft.dwLowDateTime)
End Function
All those provides various ways to convert between FILETIME
and DATETIME:
sub DoDateTest1()
dim [now] as datetime = DateTime.Now()
dim ft1 as FILETIME = [now].ToBinary()
dim ft2 as FILETIME = [now]
dim ft3 as New FILETIME(ft2.dwHighDateTime, ft2.dwLowDateTime)
dim dt4 as DateTime = ft3
dim dt5 as DateTime = dt4.AddSeconds(30)
dim ft6 as FILETIME = dt5
dim diff7 as long = ft6 - ft2
dim ft8 as FileTime = dt4.AddYears(1)
Console.WriteLine("now: {0,25} ", [now])
Console.WriteLine("ft1: {0,25} ", ft1)
Console.WriteLine("ft2: {0,25} ", ft2)
Console.WriteLine("ft3: {0,25} ", ft3)
Console.WriteLine("dt4: {0,25} ", dt4)
Console.WriteLine("dt4: {0,25} ", dt5)
Console.WriteLine("ft6: {0,25} ", ft6)
Console.WriteLine("diff7: {0,25} ", diff7)
Console.WriteLine("ft6 > ft2: {0}", ft6 > ft2) 'expect true
Console.WriteLine("ft1 = ft2: {0}", ft1 = ft2) 'expect true
Console.WriteLine("ft1 <>ft2: {0}", ft1 <> ft2) 'expect false
Console.WriteLine("ft8: {0,25} ", ft8)
end sub
My questions to the VB.NET experts:
1) Is using this structure FILETIME with all these operator going to
be a performance hit?
2) Related to #1, should I break this up? A Structure and a Class?
There were two things that made think about it:
- Desire to separate SDK library with wrapper classes;
a base SDK library with structures and API function imports,
and a wrapper library for usability.
- The SDK has many structures that use the FILETIME. Thinking
there might be RTTI and serialization overhead during the
marshalling. Even if negligible, is there a preferred
alternative to reduce redundancy?
Any tips, suggestions, comments, "Got chas?"
thanks
--